【Windows編程】系列第六篇:建立Toolbar與Statusbar

來源:互聯網
上載者:User

標籤:

上一篇我們學習瞭解了如何使用Windows GDI畫圖,該應用程式都是光光的靜態視窗,我們使用Windows應用程式,但凡稍微複雜一點的程式都會有工具列和狀態列,工具列主要用於一些快捷功能按鈕。比如典型的windows應用程式的上面是功能表列,從功能表列我們可以選擇應用程式提供的各種功能,但是有的功能比較常用,且不能放在第一級菜單,需要進入二級、三級甚至更多的菜單才能選擇。顯然這樣使用起來比較麻煩,於是這時候工具列的作用就體現出來了,一般工具列位於功能表列的下面,但是位於客戶視窗的上面。下面就是windows的文字編輯器的工具列:

Statusbar主要用於顯示應用程式的運行狀態,統計資訊,操作資訊等提示作用,一般是唯讀狀態。典型的狀態列放在視窗的最下面,比如下面就是我正在使用的Word應用程式的狀態列:

我們這次要一起學習的就是使用純Windows API函數建立基本的狀態列和功能表列。如果屬性MFC的朋友知道,如果用MFC來做工具列和功能表列很簡單。但是使用純API就麻煩一些了,當然帶來的感覺是不一樣的,比如要動態建立,使用MFC的資源編輯器就無能為力,但是對於我們今天要使用的API建立方式來說,就顯示出他的強大了。

首先,前面我們在講解Windows常用控制項的建立時就知道,所有帶視窗的控制項建立實際上都是調用Windows提供的CreateWindow或者CreateWindowEx(以下以CreateWindowEx為例)這兩個函數,當然今天的功能表列和狀態列一樣需要這兩個函數來建立。由於工具列和狀態列都是Windows的通用控制群組中的控制項,有預設的類名。建立工具列時,類名為TOOLBARCLASSNAME,建立狀態列時,類名為STATUSCLASSNAME,這兩個宏定義在commctrl.h檔案中根據是否使用UNICODE編碼分別是“ToolbarWindow32”和“msctls_statusbar32”的寬字元版本和ANSI版本。

  • 建立工具列

除了使用CreateWindowEx建立好工具列後,作為一個更好看一點,我們還可以給工具列加標以及功能提示。為了加表徵圖,最方便的方法是使用一些列映像列表API來載入和管理工具列的圖片。ImageList_Create可以建立一個圖片列表,它的原型為:

HIMAGELIST ImageList_Create(int cx, int cy, UINT flags,  int cInitial, int cGrow);

 

該函數用法在MSDN上說的比較清楚。這個列表建立後並沒有圖片,只是一個列表管理的容器,還需要載入圖片集。加入圖片所需API如下:

int ImageList_AddMasked(HIMAGELIST himl, HBITMAP hbmImage, COLORREF crMask);

 

圖片載入後,還可以設定圖片的顯示內容,包括顯示圖片、文本以及資訊提示功能。工具按鈕的響應是通過向視窗處理常式發送WM_COMMAND訊息實現的,有使用者處理按鈕事件。工具列的提示資訊是通過WM_NOTIFY訊息,由使用者佈建,工具列的建立執行個體請參看後面的應用執行個體。

  • 建立狀態列

裝具狀態列相比工具列要簡單很多,用CreateWindowEx建立狀態列後,預設情況下,狀態列只有一個顯示面板(panel),要建立多個面板,只要向狀態列把配置好個面板的長度發送SB_SETPARTS訊息即可,訊息參數分別是面板個數和個面板的終點數組。比如:

int array[3]={120,120*2,-1};SendMessage(hWndStatus,SB_SETPARTS,(WPARAM)3,(LPARAM)array);

 

表示將狀態列面板分為3各部分,第一部分到120像素為止,第二部分到240像素為止,剩下的(-1)全部分到第三部分中。

設定面板常值內容,可以給狀態列發送SB_SETTEXT訊息;要在狀態列面板中增加小表徵圖,可以給狀態發送SB_SETICON訊息。

上面的工具列和狀態列只是介紹了最基本的情況,更多的設定和訊息處理都可以參考MSDN。本系列專註在基本編程和使用上,只是介紹常見的用法,不過這些用法也夠初學者編程使用。

  • 使用執行個體

下面我們通過一個基本的執行個體程式說明如何採用純Windows API建立、使用工具列和狀態列。程式中建立的Toolbar有三個表徵圖,當程式正常顯示,滑鼠在某個工具列按鈕上移動,或者處於Disable狀態是,會有不同的圖片顯示,讀者可以自己更換其他自己喜歡的表徵圖。

#include <windows.h>#include <commctrl.h>#include <tchar.h>#pragma comment(lib, "comctl32.lib")// Windows XP sytle button#pragma comment(linker,"\"/manifestdependency:type=‘win32‘ ""name=‘Microsoft.Windows.Common-Controls‘ ""version=‘6.0.0.0‘ processorArchitecture=‘*‘ ""publicKeyToken=‘6595b64144ccf1df‘ language=‘*‘\"")#define IDC_TOOLBAR   1001#define IDC_STATUSBAR 1002//#define PIC_RESOURCE_USED#ifdef PIC_RESOURCE_USED#define IDB_NEW   110#define IDB_OPEN  111#define IDB_SAVE  112#endif#define ID_FOPEN  1111#define ID_FCLOSE 1112#define ID_FSAVE  1113static TCHAR szAppName[] = TEXT("toolbar");static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){     HWND     hWnd;     MSG      msg;     WNDCLASS wndclass;     wndclass.style         = CS_HREDRAW | CS_VREDRAW;     wndclass.lpfnWndProc   = WndProc;     wndclass.cbClsExtra    = 0;     wndclass.cbWndExtra    = 0;     wndclass.hInstance     = hInstance;     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);     wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);     wndclass.lpszMenuName  = NULL;     wndclass.lpszClassName = szAppName;     if (!RegisterClass(&wndclass))     {          MessageBox (NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);          return 0;     }     //初始化公用空間     INITCOMMONCONTROLSEX icc;     icc.dwSize = sizeof(INITCOMMONCONTROLSEX);     icc.dwICC = ICC_BAR_CLASSES;     InitCommonControlsEx(&icc);     hWnd = CreateWindow(szAppName,                  // window class name                          szAppName,                 // window caption                          WS_OVERLAPPEDWINDOW,        // window style                          CW_USEDEFAULT,              // initial x position                          CW_USEDEFAULT,              // initial y position                          400,              // initial x size                          300,              // initial y size                          NULL,                       // parent window handle                          NULL,                       // window menu handle                          hInstance,                  // program instance handle                          NULL);                     // creation parameters          ShowWindow(hWnd, iCmdShow);     UpdateWindow(hWnd);          while (GetMessage(&msg, NULL, 0, 0))     {          TranslateMessage(&msg);          DispatchMessage(&msg);     }     return msg.wParam;}HWND CreateToolbar(HWND hParentWnd){    HWND hWndTB;    TBBUTTON tbb[3];    HIMAGELIST hImageList,hHotImageList,hDisableImageList;    HBITMAP hBitmap;    HINSTANCE hInst = GetModuleHandle(NULL);    //建立Toolbar控制項    hWndTB = CreateWindowEx(0, TOOLBARCLASSNAME,TEXT(""),WS_CHILD|WS_VISIBLE|WS_BORDER|TBSTYLE_LIST|TBSTYLE_AUTOSIZE|TBSTYLE_TOOLTIPS,0,0,0,0,hParentWnd,(HMENU)IDC_TOOLBAR,hInst,NULL);    if(!hWndTB)    {        return NULL;    }    SendMessage(hWndTB, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);    //下面建立三組24x24像素大小的位元影像映像列表,用於工具列表徵圖    hImageList = ImageList_Create(24,24,ILC_COLOR24|ILC_MASK,3,1);#ifdef PIC_RESOURCE_USED    hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_COLOR3));#else    hBitmap = (HBITMAP)LoadImage(NULL, TEXT("color24x3.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION); //載入一組圖片#endif    ImageList_AddMasked(hImageList, hBitmap, RGB(255,255,255));    DeleteObject (hBitmap);    SendMessage(hWndTB,TB_SETIMAGELIST,0,(LPARAM)hImageList); //正常顯示時的映像列表    hHotImageList = ImageList_Create(24,24,ILC_COLOR24|ILC_MASK,3,1);#ifdef PIC_RESOURCE_USED    hBitmap = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_GREEN3));#else    hBitmap = (HBITMAP)LoadImage(NULL, TEXT("green24x3.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);#endif    ImageList_AddMasked(hHotImageList,hBitmap, RGB(255,255,255));    DeleteObject (hBitmap);    SendMessage(hWndTB,TB_SETHOTIMAGELIST,0,(LPARAM)hHotImageList); //滑鼠懸浮時的映像列表    hDisableImageList = ImageList_Create(24,24,ILC_COLOR24|ILC_MASK,3,1);#ifdef PIC_RESOURCE_USED    hBitmap = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_GRAY3));#else    hBitmap = (HBITMAP)LoadImage(NULL, TEXT("gray24x3.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);#endif    ImageList_AddMasked(hDisableImageList,hBitmap, RGB(255,255,255));    DeleteObject (hBitmap);    SendMessage(hWndTB,TB_SETDISABLEDIMAGELIST,0,(LPARAM)hDisableImageList); //當工具列button失能是的映像列表    ZeroMemory(tbb, sizeof(tbb));    tbb[0].iBitmap =MAKELONG(0,0) ;    tbb[0].fsState = TBSTATE_ENABLED;    tbb[0].fsStyle = TBSTYLE_BUTTON|BTNS_AUTOSIZE;    tbb[0].idCommand = ID_FOPEN;     tbb[0].iString = (INT_PTR)TEXT("開啟");    tbb[1].iBitmap =MAKELONG(1,0);    tbb[1].fsState = TBSTATE_ENABLED;    tbb[1].fsStyle = TBSTYLE_BUTTON|BTNS_AUTOSIZE;    tbb[1].idCommand = ID_FCLOSE;     tbb[1].iString = (INT_PTR)TEXT("關閉");    tbb[2].iBitmap =MAKELONG(2,0);    tbb[2].fsState = TBSTATE_ENABLED;    tbb[2].fsStyle = TBSTYLE_BUTTON|BTNS_AUTOSIZE;    tbb[2].idCommand = ID_FSAVE;    tbb[2].iString = (INT_PTR)TEXT("儲存");    SendMessage(hWndTB, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM)&tbb); //組態工具欄按鈕資訊    SendMessage(hWndTB,WM_SIZE,0,0);    return hWndTB;}HWND CreateStatusBar(HWND hParentWnd){#define PANEL_NUM 3    int array[PANEL_NUM]={120,120*2,-1};    HINSTANCE hInst = GetModuleHandle(NULL);    //建立Statusbar控制項    HWND hWndStatus = CreateWindowEx(0, STATUSCLASSNAME, TEXT(""), WS_CHILD|WS_BORDER|WS_VISIBLE, 0, 0, 0, 0, hParentWnd, (HMENU)IDC_STATUSBAR, hInst, NULL);    if (hWndStatus)    {        SendMessage(hWndStatus,SB_SETPARTS,(WPARAM)PANEL_NUM,(LPARAM)array); //設定面板個數        SendMessage(hWndStatus,SB_SETTEXT,(LPARAM)1,(WPARAM)TEXT("panel-1")); //設定第二個面板內容        SendMessage(hWndStatus,SB_SETTEXT,(LPARAM)2,(WPARAM)TEXT("panel-2")); //設定第三個面板內容    }#undef PANEL_NUM    return hWndStatus;}static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    HDC         hDC;    PAINTSTRUCT ps;    static HWND hToolbar;    static HWND hStatusbar;    switch (message)    {    case WM_CREATE:        hToolbar = CreateToolbar(hWnd);        hStatusbar = CreateStatusBar(hWnd);        return 0;    case WM_COMMAND:    {        int wmId    = LOWORD(wParam);        int wmEvent = HIWORD(wParam);        // 分析菜單選擇:        switch (wmId)        {        case ID_FOPEN:            SendMessage(hToolbar, TB_ENABLEBUTTON, (WPARAM)ID_FOPEN, (LPARAM)MAKELONG(FALSE,0));            SendMessage(hToolbar, TB_ENABLEBUTTON, (WPARAM)ID_FSAVE, (LPARAM)MAKELONG(TRUE,0));            break;        case ID_FSAVE:            SendMessage(hToolbar, TB_ENABLEBUTTON, (WPARAM)ID_FSAVE, (LPARAM)MAKELONG(FALSE,0));            SendMessage(hToolbar, TB_ENABLEBUTTON, (WPARAM)ID_FOPEN, (LPARAM)MAKELONG(TRUE,0));            break;        case ID_FCLOSE:            MessageBox(hWnd, TEXT("click!"), TEXT("hint"), MB_OK);            break;        }    }    return 0;    case WM_NOTIFY:    {        LPNMHDR lpnmhdr=(LPNMHDR)lParam;        LPTOOLTIPTEXT lpttext;        if(lpnmhdr->code==TTN_GETDISPINFO)          {            //處理滑鼠在工具列上懸浮移動時的文本提示            lpttext=(LPTOOLTIPTEXT)lParam;            switch(lpttext->hdr.idFrom)            {            case ID_FOPEN:                lpttext->lpszText=TEXT("開啟檔案");                break;            case ID_FCLOSE:                lpttext->lpszText=TEXT("關閉檔案");                break;            case ID_FSAVE:                lpttext->lpszText=TEXT("儲存為檔案");                break;            }        }    }    return 0;    case WM_SIZE:    {        SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);        SendMessage(hStatusbar, WM_SIZE, 0, 0);     }    return 0;    case WM_MOUSEMOVE:    {        TCHAR szBuf[MAX_PATH];        _stprintf(szBuf,TEXT("Mouse(%d,%d)"),LOWORD(lParam),HIWORD(lParam));        SendMessage(hStatusbar, SB_SETTEXT, 0, (LPARAM)(LPSTR)szBuf);    }    return 0;    case WM_PAINT:        hDC = BeginPaint(hWnd, &ps);        ;        EndPaint(hWnd, &ps);        return 0;    case WM_DESTROY:        PostQuitMessage(0);        return 0 ;    }    return DefWindowProc (hWnd, message, wParam, lParam);}

該執行個體程式後,結果顯示如:

該程式的工具列按下“開啟”按鈕後,自己後變成Disable狀態,點擊“儲存”後,“開啟”按鈕會再次啟用。可以看到,在滑鼠移到“儲存”按鈕上時,出現提示“儲存為檔案”的文本提示。

狀態列一共有三個面板,後面兩個在建立時靜態賦字串,第一個則即時捕獲滑鼠在客戶區中的座標位置並顯示出來。

總體來說工具列和狀態列的基本用法還是比較簡單,只是由於這兩個控制項屬於微軟的通用控制項,建立之前需要調用InitCommonControlsEx初始化通用控制項陳列庫並設定需要使用的控制項。本篇就寫到這裡,感興趣的讀者請繼續關注Windows編程基礎系列的後續文章。

 

關注公眾平台:程式員互動聯盟(coder_online),你可以第一時間擷取原創技術文章,和(java/C/C++/Android/Windows/Linux)技術大牛做朋友,線上交流編程經驗,擷取編程基礎知識,解決編程問題。程式員互動聯盟,開發人員自己的家。

轉載請註明出處,謝謝合作!

【Windows編程】系列第六篇:建立Toolbar與Statusbar

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.