2013-05-16 49 views
2

我寫的win32程序,我有一個滾動條的窗口,現在我添加了一個工具欄。 我的問題是,當我滾動窗口時,工具欄會滾動。 如何將工具欄設置在他的位置,如菜單?工具欄滾動,當我滾動窗口

這是代碼的例子,說明如何在工具欄滾動滾動窗口時,代碼是不完美的,但它顯示瞭如何將工具欄滾動,當你sroll窗口排隊,或下移行:

#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); 
    } 
} 

回答

1

大多數任何C++類庫都通過創建框架窗口來完成此操作。外部窗口是應用程序的主窗口。並創建單獨的視圖窗口以顯示內容。那些視圖窗口是那些有滾動條的窗口。即使是卑微的記事本使用這種技術:

enter image description here

注意底部的狀態欄是怎樣的框架窗口的它自己的子窗口,當你在編輯孩子使用滾動條沒有得到滾動窗口。但是,菜單不同,它位於框架窗口的非客戶端區域。非常具體的傳統菜單。您可以使用Spy ++實用程序在其他應用程序中查看他們如何組織他們的窗口。

0

有幾個選項可供選擇。

如果使用WS_CLIPCHILDREN創建主窗口,ScrollWindow()可能會忽略子窗口(包括您的工具欄)佔用的區域。我並不是100%確定的,儘管我已經使用ScrollWindowEx()與SW_SCROLLCHILDREN進行各種組合來解決子窗口滾動問題。

與您現有的代碼,另一種選擇是排除通過從區域您請求滾動工具欄佔據的面積。而不是傳遞NULL,傳遞一個客戶矩形,扣除工具欄的大小。

事情是這樣的:

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); 
+0

您的第一個兩個解決方案不起作用。 第三種解決方案是作品,而有益的,但它看起來有點彆扭,我相信有一些方法,使工具欄將不包括在父窗口的客戶區完全一樣,不包括在父窗口的菜單客戶區,並且不會隨父窗口一起滾動。 ---也許我應該設置工具欄的父窗口是菜單嗎? – user1544067

+0

菜單位於非客戶區域。如果您添加了狀態欄,您也會遇到同樣的問題,該狀態欄也會放在客戶區中。 – CoreyStup

+0

我想有一種方法可以在客戶區外創建工具欄,就像在Microsoft Word中一樣。 – user1544067

0

添加另一個級別的窗口層次結構,使滾動條和他們滾動區域是位於工具欄下方的子窗口。