处理命令带消息 翻译:tellmenow
同起命令条相比,命令带控件需要更多一些维护。差别在于,命令带控件可以改变高度,这样就要求包含命令带控件的窗口必须监视控件,并且在控件尺寸变化时重新绘制窗口,很可能还要格式化其客户区。
当用户重新排列控件的时候,命令带控件会发送许多不同的WM_NOTIFY消息。为了监控控件高度,应用程序需要检查RBN_HEIGHCHANGE通知消息并做相应回应。下面的代码演示这个过程:
// This code is inside a WM_NOTIFY message handler.
LPNMHDR pnmh;
pnmh = (LPNMHDR)lParam;
if (pnmh->code == RBN_HEIGHTCHANGE) {
InvalidateRect (hWnd, NULL, TRUE);
}
如果检测到RBN_HEIGHTCHANGE消息通知,例程就简单的使窗口客户区无效,产生一个WM_PAINT消息。接下来在处理绘制消息的代码中调用UINT CommandBands_Height (HWND hwndCmdBands)来查询命令带控件的高度,并从客户区矩形中减去该高度。和命令条一样,使用BOOL CommandBands_Show (HWND HwndCmdBands, BOOL fShow)可以隐藏或者显示命令带控件。通过调用函数BOOL CommandBands_IsVisible (HWND hwndCmdBands)可以查询控件的可视状态。
CmdBand示例
CmdBand程序演示了一个相当完整的命令带控件。示例中创建了三个带区,一个是固定菜单带区,一个是包含许多按钮的带区,一个是包含编辑控件的带区。每个带区中的透明命令条和背景位图被用在创建带背景图的命令带控件中。
通过选择View菜单中的Command Bar菜单项,可以使用一个简单的命令条来替换命令带控件。通过选择View菜单中的Command Bands,可以将命令带控件重新创建并恢复到上次的配置状态。CmdBand程序代码显示在清单5-2中。
清单5-2:CmdBand 程序
CmdBand.rc
//======================================================================
// Resource file
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include "windows.h"
#include "CmdBand.h" // Program-specific stuff
//----------------------------------------------------------------------
// Icons and bitmaps
//
ID_ICON ICON "cmdband.ico" // Program icon
CmdBarBmps BITMAP "cbarbmps.bmp" // Bmp used in cmdband image list
CmdBarEditBmp BITMAP "cbarbmp2.bmp" // Bmp used in cmdband image list
CmdBarBack BITMAP "backg2.bmp" // Bmp used for cmdband background
//----------------------------------------------------------------------
// Menu
//
ID_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&View"
BEGIN
MENUITEM "Command Bar", IDM_VIEWCMDBAR
MENUITEM "Command Band", IDM_VIEWCMDBAND
END
POPUP "&Help"
BEGIN
MENUITEM "&About...", IDM_ABOUT
END
END
//----------------------------------------------------------------------
// About box dialog template
//
aboutbox DIALOG discardable 10, 10, 160, 40
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER |
DS_MODALFRAME
CAPTION "About"
BEGIN
ICON ID_ICON, -1, 5, 5, 10, 10
LTEXT "CmdBand - Written for the book Programming Windows /
CE Copyright 2003 Douglas Boling"
-1, 40, 5, 110, 30
END
CmdBand.h
//======================================================================
// Header file
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
// Returns number of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))
//----------------------------------------------------------------------
// Generic defines and data types
//
struct decodeUINT { // Structure associates
UINT Code; // messages
// with a function.
LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);
};
struct decodeCMD { // Structure associates
UINT Code; // menu IDs with a
LRESULT (*Fxn)(HWND, WORD, HWND, WORD); // function.
};
//----------------------------------------------------------------------
// Defines used by application
//
#define IDC_CMDBAND 1 // Command band ID
#define IDC_CMDBAR 2 // Command bar ID
#define ID_ICON 10 // Icon ID
#define ID_MENU 11 // Main menu resource ID
#define IDC_EDITCTL 12
#define IDB_CMDBAND 50 // Base ID for bands
#define IDB_CMDBANDMENU 50 // Menu band ID
#define IDB_CMDBANDBTN 51 // Button band ID
#define IDB_CMDBANDEDIT 52 // Edit control band ID
// Menu item IDs
#define IDM_EXIT 100
#define IDM_VIEWCMDBAR 110
#define IDM_VIEWCMDBAND 111
#define IDM_ABOUT 120
#define NUMBANDS 3
//----------------------------------------------------------------------
// Function prototypes
//
int CreateCommandBand (HWND hWnd, BOOL fFirst);
int DestroyCommandBand (HWND hWnd);
HWND InitInstance (HINSTANCE, LPWSTR, int);
int TermInstance (HINSTANCE, int);
// Window procedures
LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);
// Message handlers
LRESULT DoCreateMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoPaintMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoNotifyMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoCommandMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);
// Command functions
LPARAM DoMainCommandViewCmdBar (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandVCmdBand (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandExit (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandAbout (HWND, WORD, HWND, WORD);
// Dialog procedures
BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM);
CmdBand.cpp
//======================================================================
// CmdBand - Dialog box demonstration
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <commctrl.h> // Command bar includes
#include "CmdBand.h" // Program-specific stuff
//----------------------------------------------------------------------
// Global data
//
const TCHAR szAppName[] = TEXT ("CmdBand");
HINSTANCE hInst; // Program instance handle
// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] = {
WM_CREATE, DoCreateMain,
WM_PAINT, DoPaintMain,
WM_NOTIFY, DoNotifyMain,
WM_COMMAND, DoCommandMain,
WM_DESTROY, DoDestroyMain,
};
// Command message dispatch for MainWindowProc
const struct decodeCMD MainCommandItems[] = {
IDM_VIEWCMDBAR, DoMainCommandViewCmdBar,
IDM_VIEWCMDBAND, DoMainCommandVCmdBand,
IDM_EXIT, DoMainCommandExit,
IDM_ABOUT, DoMainCommandAbout,
};
// Command band button initialization structure
const TBBUTTON tbCBStdBtns[] = {
// BitmapIndex Command State Style UserData String
{STD_FILENEW, 210, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{STD_FILEOPEN, 211, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{STD_FILESAVE, 212, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0},
{STD_CUT, 213, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{STD_COPY, 214, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{STD_PASTE, 215, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0},
{STD_PROPERTIES, 216, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
};
// Command bar initialization structure
const TBBUTTON tbCBViewBtns[] = {
// BitmapIndex Command State Style UserData String
{0, 0, 0,
TBSTYLE_SEP, 0, 0},
{VIEW_LARGEICONS, 210, TBSTATE_ENABLED | TBSTATE_CHECKED,
TBSTYLE_CHECKGROUP, 0, 0},
{VIEW_SMALLICONS, 211, TBSTATE_ENABLED,
TBSTYLE_CHECKGROUP, 0, 0},
{VIEW_LIST, 212, TBSTATE_ENABLED,
TBSTYLE_CHECKGROUP, 0, 0},
{VIEW_DETAILS, 213, TBSTATE_ENABLED,
TBSTYLE_CHECKGROUP, 0, 0},
{0, 0, 0, TBSTYLE_SEP, 0, 0},
{VIEW_SORTNAME, 214, TBSTATE_ENABLED | TBSTATE_CHECKED,
TBSTYLE_CHECKGROUP, 0, 0},
{VIEW_SORTTYPE, 215, TBSTATE_ENABLED,
TBSTYLE_CHECKGROUP, 0, 0},
{VIEW_SORTSIZE, 216, TBSTATE_ENABLED,
TBSTYLE_CHECKGROUP, 0, 0},
{VIEW_SORTDATE, 217, TBSTATE_ENABLED,
TBSTYLE_CHECKGROUP, 0, 0}
};
// Array that stores the band configuration
COMMANDBANDSRESTOREINFO cbr[NUMBANDS];
INT nBandOrder[NUMBANDS];
//======================================================================
// Program entry point
//
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
HWND hwndMain;
MSG msg;
// Initialize application.
hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);
if (hwndMain == 0)
return 0x10;
// Application message loop
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
// Instance cleanup
return TermInstance (hInstance, msg.wParam);
}
//----------------------------------------------------------------------
// InitInstance - Instance initialization
//
HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow){
HWND hWnd;
WNDCLASS wc;
INITCOMMONCONTROLSEX icex;
// Save program instance handle in global variable.
hInst = hInstance;
#if defined(WIN32_PLATFORM_PSPC)
// If Pocket PC, allow only one instance of the application.
hWnd = FindWindow (szAppName, NULL);
if (hWnd) {
SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));
return 0;
}
#endif
// Register application main window class.
wc.style = 0; // Window style
wc.lpfnWndProc = MainWndProc; // Callback function
wc.cbClsExtra = 0; // Extra class data
wc.cbWndExtra = 0; // Extra window data
wc.hInstance = hInstance; // Owner handle
wc.hIcon = NULL, // Application icon
wc.hCursor = LoadCursor (NULL, IDC_ARROW);// Default cursor
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL; // Menu name
wc.lpszClassName = szAppName; // Window class name
if (RegisterClass (&wc) == 0) return 0;
// Load the command bar common control class.
icex.dwSize = sizeof (INITCOMMONCONTROLSEX);
icex.dwICC = ICC_COOL_CLASSES;
InitCommonControlsEx (&icex);
// Create main window.
hWnd = CreateWindow (szAppName, TEXT ("CmdBand Demo"), WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
// Return fail code if window not created.
if (!IsWindow (hWnd)) return 0;
// Standard show and update calls
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return hWnd;
}
//----------------------------------------------------------------------
// TermInstance - Program cleanup
//
int TermInstance (HINSTANCE hInstance, int nDefRC) {
return nDefRC;
}
//======================================================================
// Message handling procedures for MainWindow
//----------------------------------------------------------------------
// MainWndProc - Callback function for application window
//
LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
INT i;
//
// Search message list to see if we need to handle this
// message. If in list, call procedure.
//
for (i = 0; i < dim(MainMessages); i++) {
if (wMsg == MainMessages[i].Code)
return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
}
return DefWindowProc (hWnd, wMsg, wParam, lParam);
}
//----------------------------------------------------------------------
// DoCreateMain - Process WM_CREATE message for window.
//
LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
CreateCommandBand (hWnd, TRUE);
return 0;
}
//----------------------------------------------------------------------
// DoPaintMain - Process WM_PAINT message for window.