如何在选项卡控件区域内添加控件?
How to add controls within tab control area?
如何获取选项卡控件区域坐标然后在该区域添加按钮?我不知道我应该使用哪个 TabCtrl_GetItemRect(), GetWindowRect() 或其他东西,因为我似乎没有得到我想要的坐标,这是选项卡控制区域,我可以在其中放置按钮。它目前位于远离选项卡控件白色区域的位置,我想将它们放置在那里,如下图所示。将它们放入此选项卡控件中的正确方法是什么?
处理这个的函数是这样的:
void CreateButtons(HWND hwnd)
{
RECT rt = {0};
//TabCtrl_GetItemRect(hTab, 0, &rt);
GetWindowRect(hTab, &rt);
//GetClientRect(hTab, &rt);
/*
wchar_t buffer[256] = {0};
wsprintf(buffer,
L"top = %d, bottom = %d, left = %d, right = %d",
rt.top, rt.bottom, rt.left, rt.right);
MessageBox(NULL, buffer, L"", MB_OK);
*/
int id = 4;
static const wchar_t *title[] = { L"Button A", L"Button B", L"Button C",
L"Button D", L"Button E", L"Button F",
L"Button G" , L"Button 001", L"Button 002",
L"Button 003", L"Button 004" };
const int nMaxButtonPerRow = 3;
const int cx_margin = 10;
const int cy_bottomMarge = 10;
const int cy_breakSize = 25;
int cx_initPos = (int)rt.left;
int cx = cx_initPos;
int cy = 50;
const int width = 80;
const int height = 25;
for(int i = 0; i < sizeof(title)/sizeof(title[0]); ++i)
{
if(i != 0 && (i % nMaxButtonPerRow) == 0) {
cy += cy_breakSize + cy_bottomMarge;
cx = cx_initPos;
}
CreateWindow(L"button", title[i],
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
cx,
cy,
width,
height,
hwnd, (HMENU) id++, NULL, NULL);
cx += width + cx_margin;
}
}
完整代码:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <Commctrl.h>
#include <crtdbg.h>
#include <strsafe.h>
#include <string.h>
#include <assert.h>
#ifdef UNICODE
#define STRSPLIT wcsrchr
#else
#define STRSPLIT strrchr
#endif
#define __FILENAME__ (STRSPLIT(TEXT(__FILE__), '/') ? STRSPLIT(TEXT(__FILE__), '/') + 1 : TEXT(__FILE__))
#define NAMEOF(s) TEXT(#s)
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK CreateTabProc(HWND, UINT, WPARAM, LPARAM);
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename);
void InitComControls();
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename);
DWORD ShowLastError(LPWSTR lpszFunction, int line, LPWSTR filename);
void InitComControls();
void CreateTab(HWND hwnd);
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text);
void CreateButtons(HWND hwnd);
HINSTANCE ghInstance;
HWND hTab;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow)
{
MSG msg = {0};
HWND hwnd;
WNDCLASSW wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
InitComControls();
if(!RegisterClass(&wc)) {
ErrorExit(NAMEOF(RegisterClass), __LINE__, __FILENAME__);
}
int width = 500;
int height = 350;
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
int cx = (screenWidth - width) / 2;
int cy = (screenHeight - height) / 2;
hwnd = CreateWindowW(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
cx, cy, width, height, NULL, NULL,
hInstance, NULL);
ghInstance = hInstance;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindowW(L"Static", L"This is label 1...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
50, 10, 130, 25, hwnd, (HMENU) 18, NULL, NULL);
CreateWindowW(L"Static", L"This is label 2...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
50, 40, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateTab(hwnd);
CreateButtons(hwnd);
//ChangeToDefaultFont(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
void CreateTab(HWND hwnd)
{
hTab =
CreateWindow(WC_TABCONTROLW, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP | WS_EX_CONTROLPARENT,
50, 80, 400, 250,
hwnd,
(HMENU) 1,
NULL,
NULL);
InsertTabItem(hTab, 2, L"Tab 1");
InsertTabItem(hTab, 3, L"Tab b");
}
void CreateButtons(HWND hwnd)
{
RECT rt = {0};
//TabCtrl_GetItemRect(hTab, 0, &rt);
GetWindowRect(hTab, &rt);
//GetClientRect(hTab, &rt);
/*
wchar_t buffer[256] = {0};
wsprintf(buffer,
L"top = %d, bottom = %d, left = %d, right = %d",
rt.top, rt.bottom, rt.left, rt.right);
MessageBox(NULL, buffer, L"", MB_OK);
*/
int id = 4;
static const wchar_t *title[] = { L"Button A", L"Button B", L"Button C",
L"Button D", L"Button E", L"Button F",
L"Button G" , L"Button 001", L"Button 002",
L"Button 003", L"Button 004" };
const int nMaxButtonPerRow = 3;
const int cx_margin = 10;
const int cy_bottomMarge = 10;
const int cy_breakSize = 25;
int cx_initPos = (int)rt.left;
int cx = cx_initPos;
int cy = 50;
const int width = 80;
const int height = 25;
for(int i = 0; i < sizeof(title)/sizeof(title[0]); ++i)
{
if(i != 0 && (i % nMaxButtonPerRow) == 0) {
cy += cy_breakSize + cy_bottomMarge;
cx = cx_initPos;
}
CreateWindow(L"button", title[i],
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
cx,
cy,
width,
height,
hwnd, (HMENU) id++, NULL, NULL);
cx += width + cx_margin;
}
}
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text)
{
TCITEMW tci = {0};
tci.mask = TCIF_TEXT;
tci.pszText = text;
tci.cchTextMax = lstrlenW(text);
SendMessage(tabHwnd, TCM_INSERTITEMW, id, (LPARAM) &tci);
}
void InitComControls()
{
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icex);
}
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename)
{
DWORD dw = ShowLastError(lpszFunction, line, filename);
ExitProcess(dw);
}
DWORD ShowLastError(LPWSTR lpszFunction, int line, LPWSTR filename)
{
#define MAX_DIGITS 16
DWORD dw = GetLastError();
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) +
lstrlen((LPCTSTR)lpszFunction) + 40 +
(line > 0 ? MAX_DIGITS : 0) +
(filename != NULL ? lstrlen(filename) : 0)) *
sizeof(TCHAR)
);
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with %d: %s"),
lpszFunction, dw, lpMsgBuf
);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
return dw;
}
更新 1: 设法用 GetWindowRect()
和 MapWindowPoints()
做到了这一点。我错过了前一个。参见 this post。它获得了正确的选项卡控件坐标,但尚未获得控件应该位于的显示区域(白色区域)。我怎样才能得到这个白色区域的坐标?如果我设法获得选项卡按钮(由 TCM_INSERTITEM
消息插入的按钮)所在的 window 区域大小,也可以工作(不确定是否非常优雅)将在设置 cx_initPos
值。
最新代码:
void CreateButtons(HWND hwnd)
{
RECT rt = GetLocalCoordinates(hTab);
int id = 4;
static const wchar_t *title[] = { L"Button A", L"Button B", L"Button C",
L"Button D", L"Button E", L"Button F",
L"Button G" , L"Button 001", L"Button 002",
L"Button 003", L"Button 004" };
const int nMaxButtonPerRow = 3;
const int cx_margin = 10;
const int cy_bottomMarge = 10;
const int cy_breakSize = 25;
int cx_initPos = rt.left;
int cx = cx_initPos;
int cy = rt.top;
const int width = 80;
const int height = 25;
for(int i = 0; i < sizeof(title)/sizeof(title[0]); ++i)
{
if(i != 0 && (i % nMaxButtonPerRow) == 0) {
cy += cy_breakSize + cy_bottomMarge;
cx = cx_initPos;
}
CreateWindow(L"button", title[i],
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
cx,
cy,
width,
height,
hwnd, (HMENU) id++, NULL, NULL);
cx += width + cx_margin;
}
}
RECT GetLocalCoordinates(HWND hWnd)
{
RECT Rect;
GetWindowRect(hWnd, &Rect);
MapWindowPoints(HWND_DESKTOP, GetParent(hWnd), (LPPOINT) &Rect, 2);
return Rect;
}
现在的样子:
如果需要在选项卡控件中添加按钮,应该将hTab
作为按钮的父class传递:
CreateButtons(hTab);
并且根据documentation:
x
Type: int
The initial horizontal position of the window. For an overlapped or
pop-up window, the x parameter is the initial x-coordinate of the
window's upper-left corner, in screen coordinates. For a child window,
x is the x-coordinate of the upper-left corner of the window relative
to the upper-left corner of the parent window's client area. If this
parameter is set to CW_USEDEFAULT, the system selects the default
position for the window's upper-left corner and ignores the y
parameter. CW_USEDEFAULT is valid only for overlapped windows; if it
is specified for a pop-up or child window, the x and y parameters are
set to zero.
所以设置的坐标是相对于parent的左上角window。不需要通过GetWindowRect
获取hTab
的位置信息,而是像下面的代码一样传递相对标签控件的位置:
int cx_initPos = 10;
int cx = cx_initPos;
对我有用:
补充:如果需要针对不同的tab页进行调整,可以参考这个。
编辑:
您可以尝试在 RECT rt = GetLocalCoordinates(hTab);
:
之后添加 TabCtrl_AdjustRect(hTab, FALSE, &rt);
RECT rt;
rt = GetLocalCoordinates(hTab);
TabCtrl_AdjustRect(hTab, FALSE, &rt);
这是你想要的结果吗:
如何获取选项卡控件区域坐标然后在该区域添加按钮?我不知道我应该使用哪个 TabCtrl_GetItemRect(), GetWindowRect() 或其他东西,因为我似乎没有得到我想要的坐标,这是选项卡控制区域,我可以在其中放置按钮。它目前位于远离选项卡控件白色区域的位置,我想将它们放置在那里,如下图所示。将它们放入此选项卡控件中的正确方法是什么?
处理这个的函数是这样的:
void CreateButtons(HWND hwnd)
{
RECT rt = {0};
//TabCtrl_GetItemRect(hTab, 0, &rt);
GetWindowRect(hTab, &rt);
//GetClientRect(hTab, &rt);
/*
wchar_t buffer[256] = {0};
wsprintf(buffer,
L"top = %d, bottom = %d, left = %d, right = %d",
rt.top, rt.bottom, rt.left, rt.right);
MessageBox(NULL, buffer, L"", MB_OK);
*/
int id = 4;
static const wchar_t *title[] = { L"Button A", L"Button B", L"Button C",
L"Button D", L"Button E", L"Button F",
L"Button G" , L"Button 001", L"Button 002",
L"Button 003", L"Button 004" };
const int nMaxButtonPerRow = 3;
const int cx_margin = 10;
const int cy_bottomMarge = 10;
const int cy_breakSize = 25;
int cx_initPos = (int)rt.left;
int cx = cx_initPos;
int cy = 50;
const int width = 80;
const int height = 25;
for(int i = 0; i < sizeof(title)/sizeof(title[0]); ++i)
{
if(i != 0 && (i % nMaxButtonPerRow) == 0) {
cy += cy_breakSize + cy_bottomMarge;
cx = cx_initPos;
}
CreateWindow(L"button", title[i],
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
cx,
cy,
width,
height,
hwnd, (HMENU) id++, NULL, NULL);
cx += width + cx_margin;
}
}
完整代码:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <Commctrl.h>
#include <crtdbg.h>
#include <strsafe.h>
#include <string.h>
#include <assert.h>
#ifdef UNICODE
#define STRSPLIT wcsrchr
#else
#define STRSPLIT strrchr
#endif
#define __FILENAME__ (STRSPLIT(TEXT(__FILE__), '/') ? STRSPLIT(TEXT(__FILE__), '/') + 1 : TEXT(__FILE__))
#define NAMEOF(s) TEXT(#s)
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK CreateTabProc(HWND, UINT, WPARAM, LPARAM);
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename);
void InitComControls();
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename);
DWORD ShowLastError(LPWSTR lpszFunction, int line, LPWSTR filename);
void InitComControls();
void CreateTab(HWND hwnd);
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text);
void CreateButtons(HWND hwnd);
HINSTANCE ghInstance;
HWND hTab;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow)
{
MSG msg = {0};
HWND hwnd;
WNDCLASSW wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
InitComControls();
if(!RegisterClass(&wc)) {
ErrorExit(NAMEOF(RegisterClass), __LINE__, __FILENAME__);
}
int width = 500;
int height = 350;
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
int cx = (screenWidth - width) / 2;
int cy = (screenHeight - height) / 2;
hwnd = CreateWindowW(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
cx, cy, width, height, NULL, NULL,
hInstance, NULL);
ghInstance = hInstance;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindowW(L"Static", L"This is label 1...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
50, 10, 130, 25, hwnd, (HMENU) 18, NULL, NULL);
CreateWindowW(L"Static", L"This is label 2...",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
50, 40, 130, 25, hwnd, (HMENU) 19, NULL, NULL);
CreateTab(hwnd);
CreateButtons(hwnd);
//ChangeToDefaultFont(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
void CreateTab(HWND hwnd)
{
hTab =
CreateWindow(WC_TABCONTROLW, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP | WS_EX_CONTROLPARENT,
50, 80, 400, 250,
hwnd,
(HMENU) 1,
NULL,
NULL);
InsertTabItem(hTab, 2, L"Tab 1");
InsertTabItem(hTab, 3, L"Tab b");
}
void CreateButtons(HWND hwnd)
{
RECT rt = {0};
//TabCtrl_GetItemRect(hTab, 0, &rt);
GetWindowRect(hTab, &rt);
//GetClientRect(hTab, &rt);
/*
wchar_t buffer[256] = {0};
wsprintf(buffer,
L"top = %d, bottom = %d, left = %d, right = %d",
rt.top, rt.bottom, rt.left, rt.right);
MessageBox(NULL, buffer, L"", MB_OK);
*/
int id = 4;
static const wchar_t *title[] = { L"Button A", L"Button B", L"Button C",
L"Button D", L"Button E", L"Button F",
L"Button G" , L"Button 001", L"Button 002",
L"Button 003", L"Button 004" };
const int nMaxButtonPerRow = 3;
const int cx_margin = 10;
const int cy_bottomMarge = 10;
const int cy_breakSize = 25;
int cx_initPos = (int)rt.left;
int cx = cx_initPos;
int cy = 50;
const int width = 80;
const int height = 25;
for(int i = 0; i < sizeof(title)/sizeof(title[0]); ++i)
{
if(i != 0 && (i % nMaxButtonPerRow) == 0) {
cy += cy_breakSize + cy_bottomMarge;
cx = cx_initPos;
}
CreateWindow(L"button", title[i],
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
cx,
cy,
width,
height,
hwnd, (HMENU) id++, NULL, NULL);
cx += width + cx_margin;
}
}
void InsertTabItem(HWND tabHwnd, UINT id, LPWSTR text)
{
TCITEMW tci = {0};
tci.mask = TCIF_TEXT;
tci.pszText = text;
tci.cchTextMax = lstrlenW(text);
SendMessage(tabHwnd, TCM_INSERTITEMW, id, (LPARAM) &tci);
}
void InitComControls()
{
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icex);
}
void ErrorExit(LPWSTR lpszFunction, int line, LPWSTR filename)
{
DWORD dw = ShowLastError(lpszFunction, line, filename);
ExitProcess(dw);
}
DWORD ShowLastError(LPWSTR lpszFunction, int line, LPWSTR filename)
{
#define MAX_DIGITS 16
DWORD dw = GetLastError();
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) +
lstrlen((LPCTSTR)lpszFunction) + 40 +
(line > 0 ? MAX_DIGITS : 0) +
(filename != NULL ? lstrlen(filename) : 0)) *
sizeof(TCHAR)
);
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with %d: %s"),
lpszFunction, dw, lpMsgBuf
);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
return dw;
}
更新 1: 设法用 GetWindowRect()
和 MapWindowPoints()
做到了这一点。我错过了前一个。参见 this post。它获得了正确的选项卡控件坐标,但尚未获得控件应该位于的显示区域(白色区域)。我怎样才能得到这个白色区域的坐标?如果我设法获得选项卡按钮(由 TCM_INSERTITEM
消息插入的按钮)所在的 window 区域大小,也可以工作(不确定是否非常优雅)将在设置 cx_initPos
值。
最新代码:
void CreateButtons(HWND hwnd)
{
RECT rt = GetLocalCoordinates(hTab);
int id = 4;
static const wchar_t *title[] = { L"Button A", L"Button B", L"Button C",
L"Button D", L"Button E", L"Button F",
L"Button G" , L"Button 001", L"Button 002",
L"Button 003", L"Button 004" };
const int nMaxButtonPerRow = 3;
const int cx_margin = 10;
const int cy_bottomMarge = 10;
const int cy_breakSize = 25;
int cx_initPos = rt.left;
int cx = cx_initPos;
int cy = rt.top;
const int width = 80;
const int height = 25;
for(int i = 0; i < sizeof(title)/sizeof(title[0]); ++i)
{
if(i != 0 && (i % nMaxButtonPerRow) == 0) {
cy += cy_breakSize + cy_bottomMarge;
cx = cx_initPos;
}
CreateWindow(L"button", title[i],
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
cx,
cy,
width,
height,
hwnd, (HMENU) id++, NULL, NULL);
cx += width + cx_margin;
}
}
RECT GetLocalCoordinates(HWND hWnd)
{
RECT Rect;
GetWindowRect(hWnd, &Rect);
MapWindowPoints(HWND_DESKTOP, GetParent(hWnd), (LPPOINT) &Rect, 2);
return Rect;
}
现在的样子:
如果需要在选项卡控件中添加按钮,应该将hTab
作为按钮的父class传递:
CreateButtons(hTab);
并且根据documentation:
x
Type: int
The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area. If this parameter is set to CW_USEDEFAULT, the system selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero.
所以设置的坐标是相对于parent的左上角window。不需要通过GetWindowRect
获取hTab
的位置信息,而是像下面的代码一样传递相对标签控件的位置:
int cx_initPos = 10;
int cx = cx_initPos;
对我有用:
补充:如果需要针对不同的tab页进行调整,可以参考这个
编辑:
您可以尝试在 RECT rt = GetLocalCoordinates(hTab);
:
TabCtrl_AdjustRect(hTab, FALSE, &rt);
RECT rt;
rt = GetLocalCoordinates(hTab);
TabCtrl_AdjustRect(hTab, FALSE, &rt);
这是你想要的结果吗: