Reputation: 1764
I am writing win32 program, and I have a window with a scroll bar, and now I added a toolbar. My problem is, the toolbar is scrolls when I scrolling the window. how do I set the toolbar to stand in his place, such as a menu?
This is an example of code that shows how the toolbar scrolls when scrolling the window, the code is not perfect, but it shows how the toolbar scroll when you sroll the window line up, or line down:
#include <windows.h>
#include <stdlib.h>
#include <CommCtrl.h>
#pragma comment(lib, "comctl32.lib")
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE instance;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
instance = hInstance;
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"Example";
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
RegisterClassEx(&wcex);
HWND hWnd = CreateWindow(L"Example", L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
500, 500, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
// create toolbar
HWND hWndToolbar = CreateWindowEx(0 , TOOLBARCLASSNAME, NULL, WS_CHILD | TBSTYLE_TOOLTIPS,
0, 0, 0, 0, hWnd, (HMENU)0, instance, NULL);
HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLOR16 | ILC_MASK, 3, 0);
SendMessage(hWndToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hImageList);
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
TBBUTTON tbb[4] =
{
{0,0,TBSTATE_ENABLED,TBSTYLE_BUTTON,},
{1,1,TBSTATE_ENABLED,TBSTYLE_BUTTON,},
{2,2,TBSTATE_ENABLED,TBSTYLE_BUTTON,},
{0,0,TBSTATE_ENABLED,BTNS_SEP}
};
SendMessage(hWndToolbar, (UINT) TB_ADDBUTTONS, 4, (LPARAM)&tbb);
SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
ShowWindow(hWndToolbar , SW_SHOW);
// scrollbar
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
si.nMax = 1000;
si.nMin = 0;
si.nPos = 0;
si.nPage = 500;
SetScrollInfo(hWnd, SBS_VERT, &si, TRUE);
}
break;
case WM_VSCROLL:
switch(LOWORD(wParam))
{
case SB_LINEDOWN:
ScrollWindow(hWnd, 0, -20, NULL, NULL);
break;
case SB_LINEUP:
ScrollWindow(hWnd, 0, 20, NULL, NULL);
break;
}
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
Upvotes: 2
Views: 800
Reputation: 941277
Most any C++ class library does this by creating a frame window. The outer window that's the main window of the app. And creates separate view windows to display content. Those view windows are the ones that have a scrollbar. Even the lowly Notepad uses this technique:
Note how the status bar at the bottom is its own child window of the frame window and doesn't get scrolled when you use the scroll bars in the edit child window. The menu is different however, that's in the non-client area of the frame window. Very specific to traditional menus. You can use the Spy++ utility to poke around in other apps to see how they organized their windows.
Upvotes: 1
Reputation: 37122
Add another level to the window hierarchy, so that the scrollbars and the area they scroll are in a child window positioned below the toolbar.
Upvotes: 0
Reputation: 1488
There are a couple options to try.
If you create your host window with WS_CLIPCHILDREN, ScrollWindow() may ignore areas taken up by child windows (including your toolbar). I'm not 100% sure that's the case, although I've used ScrollWindowEx() in various combinations with SW_SCROLLCHILDREN to solve child window scrolling.
Another option with your existing code would be to exclude the area taken by the toolbar from your region you're requesting to scroll. Instead of passing NULL, pass a client rectangle, deducting for the size of your toolbar.
Something like this:
RECT toolRect;
GetClientRect(hWndToolbar, &toolRect);
RECT clientRect;
GetClientRect(hWnd, &clientRect);
// Adjust clientrect by the height of the toolbar
clientRect.top += toolRect.bottom;
// Scroll the region of our client area minus the toolbar at the top
ScrollWindow(hWnd, 0, 20, &clientRect, NULL);
Upvotes: 0