子窗口中的工具栏表现得很奇怪
好的,所以我使用 win32,目前使用尽可能少的额外库。我的应用程序使用分隔条分为多个子窗口,并且我在主窗口中添加了工具栏和状态栏。现在,我尝试向其中一个子窗口添加一个工具栏,它可以工作,但是一旦发生 WM_SIZE,按钮就会消失。顺便说一下,这一切都是在主窗口的 WndProc 中完成的。这是创建子窗口工具栏的代码:
toolRender = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS,
0, 0, 0, 0, wndRender, NULL, gHinst, 0);
SendMessage(toolRender, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SendMessage(toolRender, CCM_SETVERSION, (WPARAM)5, 0);
himl = ImageList_LoadImage(NULL, L"buttons.bmp", 16, 2, RGB(0, 255, 255), IMAGE_BITMAP, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
SendMessage(toolRender, TB_SETIMAGELIST, 0, (LPARAM)himl);
TBBUTTON tbb2[2];
memset(tbb2, 0, sizeof(tbb2));
tbb2[0].iBitmap = 0;
tbb2[0].fsState = TBSTATE_ENABLED;
tbb2[0].fsStyle = TBSTYLE_BUTTON;
tbb2[0].idCommand = TOOL_SAVEALL;
tbb2[0].iString = (INT_PTR)L"Save All";
tbb2[1].iBitmap = 1;
tbb2[1].fsState = TBSTATE_ENABLED;
tbb2[1].fsStyle = TBSTYLE_BUTTON;
tbb2[1].idCommand = TOOL_HELP;
tbb2[1].iString = (INT_PTR)L"Help";
SendMessage(toolRender, TB_SETMAXTEXTROWS, 0, 0);
SendMessage(toolRender, TB_ADDBUTTONS, sizeof(tbb2)/sizeof(TBBUTTON), (LPARAM)&tbb2);
这是我的整个 WM_SIZE 消息:
case WM_SIZE :
{
GetClientRect(hwnd, &rect);
// Resize toolbar
SendMessage(toolMain, TB_AUTOSIZE, 0, 0);
SendMessage(toolRender, TB_AUTOSIZE, 0, 0);
SendMessage(statusMain, WM_SIZE, 0, 0);
GetWindowRect(toolMain, &toolrect);
GetWindowRect(statusMain, &statusrect);
toolHeight = toolrect.bottom - toolrect.top;
statusHeight = statusrect.bottom - statusrect.top;
windowHeight = rect.bottom - rect.top;
GetWindowRect(toolRender, &toolrect);
toolRendHeight = toolrect.bottom - toolrect.top;
//Make sure window isn't too small
if (rect.right < MINSIZE * 4)
{
rect.right = MINSIZE * 4;
forceresize = true;
}
if (windowHeight < toolHeight + statusHeight + toolRendHeight + (MINSIZE * 2))
{
rect.bottom = toolHeight + statusHeight + toolRendHeight + (MINSIZE * 2);
forceresize = true;
}
//resize splitters
xDiv1 = rect.right * xDiv1p;
xDiv2 = rect.right * xDiv2p;
xDiv3 = rect.right * xDiv3p;
yDiv = rect.bottom * yDivp;
// Make sure splitters aren't beyond bounds
if (xDiv3 > rect.right - MINSIZE)
xDiv3 = rect.right - MINSIZE;
else if(xDiv3 < xDiv2 + MINSIZE)
xDiv3 = xDiv2 + MINSIZE;
if (xDiv2 > xDiv3 - MINSIZE)
xDiv2 = xDiv3 - MINSIZE;
else if (xDiv3 < xDiv1 + MINSIZE)
xDiv2 = xDiv1 + MINSIZE;
if (xDiv1 > xDiv2 - MINSIZE)
xDiv1 = xDiv2 - MINSIZE;
else if (xDiv1 < MINSIZE)
xDiv1 = MINSIZE;
if (yDiv > rect.bottom - MINSIZE)
yDiv = rect.bottom - MINSIZE;
else if(yDiv < MINSIZE + toolrect.bottom)
yDiv = MINSIZE + toolrect.bottom;
// Resize windows
MoveWindow(wndObjBrowser, 0, toolHeight, xDiv1 - SBS, windowHeight - toolHeight - statusHeight, FALSE);
MoveWindow(wndObjList, xDiv1 + SBS, toolHeight, xDiv2 - xDiv1 - (SBS * 2), windowHeight - toolHeight - statusHeight, FALSE);
if (!bDualMonitor)
{
MoveWindow(wndRender, xDiv2 + SBS, toolHeight, rect.right - xDiv2 - SBS, yDiv - toolHeight - SBS, FALSE);
//SendMessage(toolRender, TB_AUTOSIZE, 0, 0);
MoveWindow(wndAreaList, xDiv2 + SBS, yDiv + SBS, xDiv3 - xDiv2 - (SBS * 2), windowHeight - statusHeight - yDiv - SBS, FALSE);
MoveWindow(wndAreaInfo, xDiv3 + SBS, yDiv + SBS, rect.right - xDiv3 - SBS, windowHeight - statusHeight - yDiv - SBS, FALSE);
}
else if (bDualMonitor)
{
MoveWindow(wndAreaList, xDiv2 + SBS, toolHeight, rect.right - xDiv2 - SBS, yDiv - toolHeight, FALSE);
MoveWindow(wndAreaInfo, xDiv2 + SBS, yDiv + SBS, rect.right - xDiv2 - SBS, windowHeight - statusHeight - yDiv - SBS, FALSE);
}
if (forceresize)
MoveWindow(hwnd, rect.left, rect.top, rect.right, rect.bottom, FALSE);
InvalidateRect(hwnd, &rect, TRUE);
}
break; //WM_SIZE
有什么想法吗?
Okay, so I'm using win32, with as few extra libraries as possible for the moment. My application is divided into multiple child windows using splitterbars, and I've added a toolbar and status bar to the main window. Now, I'm trying to add a toolbar to one of the child windows, and it works, but as soon as WM_SIZE happens, the buttons dissapear. This is all done in the WndProc for the Main window, by the way. Here's the code that creates the child window's toolbar:
toolRender = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS,
0, 0, 0, 0, wndRender, NULL, gHinst, 0);
SendMessage(toolRender, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
SendMessage(toolRender, CCM_SETVERSION, (WPARAM)5, 0);
himl = ImageList_LoadImage(NULL, L"buttons.bmp", 16, 2, RGB(0, 255, 255), IMAGE_BITMAP, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
SendMessage(toolRender, TB_SETIMAGELIST, 0, (LPARAM)himl);
TBBUTTON tbb2[2];
memset(tbb2, 0, sizeof(tbb2));
tbb2[0].iBitmap = 0;
tbb2[0].fsState = TBSTATE_ENABLED;
tbb2[0].fsStyle = TBSTYLE_BUTTON;
tbb2[0].idCommand = TOOL_SAVEALL;
tbb2[0].iString = (INT_PTR)L"Save All";
tbb2[1].iBitmap = 1;
tbb2[1].fsState = TBSTATE_ENABLED;
tbb2[1].fsStyle = TBSTYLE_BUTTON;
tbb2[1].idCommand = TOOL_HELP;
tbb2[1].iString = (INT_PTR)L"Help";
SendMessage(toolRender, TB_SETMAXTEXTROWS, 0, 0);
SendMessage(toolRender, TB_ADDBUTTONS, sizeof(tbb2)/sizeof(TBBUTTON), (LPARAM)&tbb2);
And here's my entire WM_SIZE message:
case WM_SIZE :
{
GetClientRect(hwnd, &rect);
// Resize toolbar
SendMessage(toolMain, TB_AUTOSIZE, 0, 0);
SendMessage(toolRender, TB_AUTOSIZE, 0, 0);
SendMessage(statusMain, WM_SIZE, 0, 0);
GetWindowRect(toolMain, &toolrect);
GetWindowRect(statusMain, &statusrect);
toolHeight = toolrect.bottom - toolrect.top;
statusHeight = statusrect.bottom - statusrect.top;
windowHeight = rect.bottom - rect.top;
GetWindowRect(toolRender, &toolrect);
toolRendHeight = toolrect.bottom - toolrect.top;
//Make sure window isn't too small
if (rect.right < MINSIZE * 4)
{
rect.right = MINSIZE * 4;
forceresize = true;
}
if (windowHeight < toolHeight + statusHeight + toolRendHeight + (MINSIZE * 2))
{
rect.bottom = toolHeight + statusHeight + toolRendHeight + (MINSIZE * 2);
forceresize = true;
}
//resize splitters
xDiv1 = rect.right * xDiv1p;
xDiv2 = rect.right * xDiv2p;
xDiv3 = rect.right * xDiv3p;
yDiv = rect.bottom * yDivp;
// Make sure splitters aren't beyond bounds
if (xDiv3 > rect.right - MINSIZE)
xDiv3 = rect.right - MINSIZE;
else if(xDiv3 < xDiv2 + MINSIZE)
xDiv3 = xDiv2 + MINSIZE;
if (xDiv2 > xDiv3 - MINSIZE)
xDiv2 = xDiv3 - MINSIZE;
else if (xDiv3 < xDiv1 + MINSIZE)
xDiv2 = xDiv1 + MINSIZE;
if (xDiv1 > xDiv2 - MINSIZE)
xDiv1 = xDiv2 - MINSIZE;
else if (xDiv1 < MINSIZE)
xDiv1 = MINSIZE;
if (yDiv > rect.bottom - MINSIZE)
yDiv = rect.bottom - MINSIZE;
else if(yDiv < MINSIZE + toolrect.bottom)
yDiv = MINSIZE + toolrect.bottom;
// Resize windows
MoveWindow(wndObjBrowser, 0, toolHeight, xDiv1 - SBS, windowHeight - toolHeight - statusHeight, FALSE);
MoveWindow(wndObjList, xDiv1 + SBS, toolHeight, xDiv2 - xDiv1 - (SBS * 2), windowHeight - toolHeight - statusHeight, FALSE);
if (!bDualMonitor)
{
MoveWindow(wndRender, xDiv2 + SBS, toolHeight, rect.right - xDiv2 - SBS, yDiv - toolHeight - SBS, FALSE);
//SendMessage(toolRender, TB_AUTOSIZE, 0, 0);
MoveWindow(wndAreaList, xDiv2 + SBS, yDiv + SBS, xDiv3 - xDiv2 - (SBS * 2), windowHeight - statusHeight - yDiv - SBS, FALSE);
MoveWindow(wndAreaInfo, xDiv3 + SBS, yDiv + SBS, rect.right - xDiv3 - SBS, windowHeight - statusHeight - yDiv - SBS, FALSE);
}
else if (bDualMonitor)
{
MoveWindow(wndAreaList, xDiv2 + SBS, toolHeight, rect.right - xDiv2 - SBS, yDiv - toolHeight, FALSE);
MoveWindow(wndAreaInfo, xDiv2 + SBS, yDiv + SBS, rect.right - xDiv2 - SBS, windowHeight - statusHeight - yDiv - SBS, FALSE);
}
if (forceresize)
MoveWindow(hwnd, rect.left, rect.top, rect.right, rect.bottom, FALSE);
InvalidateRect(hwnd, &rect, TRUE);
}
break; //WM_SIZE
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为什么在大多数 MoveWindow 调用中为 bRepaint 参数传递 FALSE?最后的 InvalidateRect 仅使当前窗口无效,而不是其子窗口。
Why are you passing FALSE for the bRepaint parameter in most of the MoveWindow calls? The InvalidateRect at the end only invalidates the current window, not its children.