=============================================================
标题:资源脚本
备注:参考《Windows CE 6.0开发者参考》
日期:2011.4.1
姓名:朱铭雷
=============================================================
主要功能
用来存放对话框,字符串,位图,图标,菜单等资源数据。因为资源不需编译,所以可直接修改资源而无需重新编译整个应用程序。
菜单
ID_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New", IDM_NEW
MENUITEM "&Open", IDM_OPEN
MENUITEM SEPARATOR
MENUITEM "&Exit", IDM_EXIT
END
END
ID_MENU是资源ID,接着MENU是资源类型,DISCARDABLE关键字告诉系统在该资源没被用到时可以从内存中删除。POPUP指明File菜单项是附加在主菜单上的弹出式菜单。&后面的字符作为加速键分配给这个菜单项。语法比较清晰,很容易看懂。
在代码中使用该菜单资源:
HMENU hMenuMain, hMenu;
MapWindowPoints (hWnd, HWND_DESKTOP, &pt, 1);
pt.x += 5;
hMenuMain = LoadMenu (hInst, MAKEINTRESOURCE (ID_MENU));
hMenu = GetSubMenu (hMenuMain, 0);
TPMPARAMS tpm;
tpm.cbSize = sizeof (tpm);
GetClientRect (hWnd, &tpm.rcExclude);
TrackPopupMenuEx (hMenu, TPM_LEFTALIGN | TPM_TOPALIGN,
pt.x, pt.y, hWnd, &tpm);
DestroyMenu (hMenuMain);
DestroyMenu (hMenu);
图标
ID_ICON ICON "res//WRENCH.ICO"
在代码中使用该图标资源:
HICON hIcon = (HICON)SendMessage(hWnd, WM_GETICON, FALSE, 0);
if (hIcon == 0)
{
hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(ID_ICON), IMAGE_ICON, 16, 16, 0);
SendMessage(hWnd, WM_SETICON, FALSE, (LPARAM)hIcon);
}
这段代码的功能是给窗口分配图标。
加速键
提供一种直接的方法,使一个按键组合可以触发WM_COMMAND消息并发送到一个窗口。
ID_ACCEL ACCELERATORS DISCARDABLE
BEGIN
"E", IDM_EXIT, VIRTKEY, CONTROL
END
VIRTKEY代表这个字实际上是虚拟键,CONTROL表示Ctrl键必须同时按下。
在代码中使用该加速键资源:
HACCEL hAccel;
hAccel = LoadAccelerators (hInst, MAKEINTRESOURCE (ID_ACCEL));
MSG msg;
while (GetMessage (&msg, NULL, 0, 0))
{
// Translate accelerators
if (!TranslateAccelerator (hwndMain, hAccel, &msg))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
这段代码首先加载加速键表,然后对消息循环做简单修改,以使加速键起作用。
位图
IDB_BITMAP BITMAP "res//abc.bmp"
在代码中使用该位图资源:
RECT rect;
GetClientRect (hWnd, &rect);
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint (hWnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, 20, 20);
HBITMAP hOldMemBmp = (HBITMAP)SelectObject(hdcMem,hBitmap);
HDC hdcBmp = CreateCompatibleDC(hdc);
HANDLE hBmpDis = LoadImage(hInst,MAKEINTRESOURCE(IDB_BITMAP), IMAGE_BITMAP, 0, 0, 0);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcBmp,hBmpDis);
BitBlt(hdcMem, 0, 0, 20, 20, hdcBmp, 0, 0, SRCCOPY);
BitBlt(hdc, 0, 0, 20, 20, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcBmp,hOldBmp);
SelectObject(hdcMem,hOldMemBmp);
DeleteObject(hBitmap);
DeleteDC(hdcMem);
DeleteDC(hdcBmp);
EndPaint (hWnd, &ps);
这段代码采用双缓存绘制位图。
字符串
STRINGTABLE DISCARDABLE
BEGIN
IDS_TEXT1, "Hello "
IDS_TEXT2, "Windows CE!"
END
在代码中使用该字符串资源:
PBYTE pRes, pBuff;
int nStrLen = 0, i = 0;
pBuff = (PBYTE)LocalAlloc (LPTR, 8);
while (pRes = (PBYTE)LoadString (hInst, IDS_TEXT1 + i++, NULL, 0))
{
// Get the length of the string resource
int nLen = *(PWORD)(pRes-2) * sizeof (TCHAR);
// Resize buffer
pBuff = (PBYTE)LocalReAlloc (pBuff, nStrLen + 8 + nLen, LMEM_MOVEABLE | LMEM_ZEROINIT);
if (pBuff == NULL) return 0;
// Copy resource into buffer
memcpy (pBuff + nStrLen, pRes, nLen);
nStrLen += nLen;
}
*(TCHAR *)(pBuff + nStrLen) = TEXT ('/0');
LPTSTR pszText;
pszText = (LPTSTR)pBuff;
DrawText (hdc, pszText, -1, &rect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
这段代码输出字符串Hello Windows CE!
完整测试程序
HelloCE.rc
#include "windows.h"
#include "HelloCE.h"
//----------------------------------------------------------------------
// Main window dialog template
//
ProgWinCE DIALOG discardable 10, 10, 120, 65
STYLE WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_SYSMENU |
DS_CENTER | DS_MODALFRAME
CAPTION "ProgWinCE"
BEGIN
LISTBOX IDD_NETLIST, 2, 2, 116, 46,
WS_TABSTOP | WS_VSCROLL |
LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS
PUSHBUTTON "Exit", IDC_EXIT, 2, 50, 55, 12, WS_TABSTOP
END
//----------------------------------------------------------------------
// Menu
//
ID_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New", IDM_NEW
MENUITEM "&Open", IDM_OPEN
MENUITEM SEPARATOR
MENUITEM "&Exit", IDM_EXIT
END
END
//----------------------------------------------------------------------
// Icon
//
ID_ICON ICON "res//WRENCH.ICO"
//----------------------------------------------------------------------
// Accelorator
//
ID_ACCEL ACCELERATORS DISCARDABLE
BEGIN
"E", IDM_EXIT, VIRTKEY, CONTROL
END
//----------------------------------------------------------------------
// Bitmap
//
IDB_BITMAP BITMAP "res//abc.bmp"
//----------------------------------------------------------------------
// String table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_TEXT1, "Hello "
IDS_TEXT2, "Windows CE!"
END
HelloCE.h
#define ID_MENU 10
#define IDM_NEW 100
#define IDM_OPEN 101
#define IDM_EXIT 102
#define ID_ICON 11
#define ID_ACCEL 12
#define IDB_BITMAP 13
#define IDS_TEXT1 14
#define IDS_TEXT2 15
#define IDD_NETLIST 103
#define IDC_EXIT 104
// Returns number of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))
//----------------------------------------------------------------------
// Generic defines and data types
//
struct decodeUINT
{ // Structure associates
UINT Code; // messages
LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);// with a function.
};
struct decodeCMD
{ // Structure associates
UINT Code; // menu IDs
LRESULT (*Fxn)(HWND, WORD, HWND, WORD); // with a function
};
//----------------------------------------------------------------------
// Function prototypes
//
HWND InitInstance (HINSTANCE, LPWSTR, int);
int TermInstance (HINSTANCE, int);
int ShowContextMenu (HWND hWnd, POINT pt);
// Window procedures
LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);
// Message handlers
LRESULT DoPaintMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoLButtonDownMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoCommandMain (HWND, UINT, WPARAM, LPARAM);
// Command functions
LPARAM DoMainCommandExit (HWND, WORD, HWND, WORD);
HelloCE.cpp
#include <windows.h>
#include "helloce.h"
#include <aygshell.h>
#pragma comment( lib, "aygshell" )
//----------------------------------------------------------------------
// Global data
//
const TCHAR szAppName[] = TEXT("ProgWinCE");
HINSTANCE hInst; // Program instance handle
LPTSTR pszText;
// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] =
{
WM_PAINT, DoPaintMain,
WM_DESTROY, DoDestroyMain,
WM_LBUTTONDOWN, DoLButtonDownMain,
WM_COMMAND, DoCommandMain,
};
// Command Message dispatch for MainWindowProc
const struct decodeCMD MainCommandItems[] =
{
IDM_EXIT, DoMainCommandExit,
};
//======================================================================
// Program entry point
//
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow)
{
// Initialize this instance.
HWND hwndMain;
hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);
if (hwndMain == 0) return 0x10;
// Load accelerator table.
HACCEL hAccel;
hAccel = LoadAccelerators (hInst, MAKEINTRESOURCE (ID_ACCEL));
// Application message loop
MSG msg;
while (GetMessage (&msg, NULL, 0, 0))
{
// Translate accelerators
if (!TranslateAccelerator (hwndMain, hAccel, &msg))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
// Instance cleanup
return TermInstance (hInstance, msg.wParam);
}
//----------------------------------------------------------------------
// InitInstance - Instance initialization
//
HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow)
{
// Save program instance handle in global variable.
hInst = hInstance;
// Load text from multiple string resources into one large buffer
PBYTE pRes, pBuff;
int nStrLen = 0, i = 0;
pBuff = (PBYTE)LocalAlloc (LPTR, 8);
while (pRes = (PBYTE)LoadString (hInst, IDS_TEXT1 + i++, NULL, 0))
{
// Get the length of the string resource
int nLen = *(PWORD)(pRes-2) * sizeof (TCHAR);
// Resize buffer
pBuff = (PBYTE)LocalReAlloc (pBuff, nStrLen + 8 + nLen, LMEM_MOVEABLE | LMEM_ZEROINIT);
if (pBuff == NULL) return 0;
// Copy resource into buffer
memcpy (pBuff + nStrLen, pRes, nLen);
nStrLen += nLen;
}
*(TCHAR *)(pBuff + nStrLen) = TEXT ('/0');
pszText = (LPTSTR)pBuff;
// Register application main window class.
WNDCLASS wc;
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;
// Create main window.
HWND hWnd;
hWnd = CreateWindow (szAppName, // Window class
TEXT("ProgWinCE"), // Window title
// Style flags
WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, // x position
CW_USEDEFAULT, // y position
CW_USEDEFAULT, // Initial width
CW_USEDEFAULT, // Initial height
NULL, // Parent
NULL, // Menu, must be null
hInstance, // Application instance
NULL); // Pointer to create
// parameters
if (!IsWindow (hWnd)) return 0; // Fail code if not created.
// Standard show and update calls
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
HICON hIcon = (HICON)SendMessage(hWnd, WM_GETICON, FALSE, 0);
if (hIcon == 0)
{
hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(ID_ICON), IMAGE_ICON, 16, 16, 0);
SendMessage(hWnd, WM_SETICON, FALSE, (LPARAM)hIcon);
}
return hWnd;
}
//----------------------------------------------------------------------
// TermInstance - Program cleanup
//
int TermInstance (HINSTANCE hInstance, int nDefRC)
{
LocalFree (pszText);
return nDefRC;
}
//======================================================================
// Message handling procedures for main window
//
//----------------------------------------------------------------------
// 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);
}
//----------------------------------------------------------------------
// DoPaintMain - Process WM_PAINT message for window.
//
LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam)
{
// Get the size of the client rectangle
RECT rect;
GetClientRect (hWnd, &rect);
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint (hWnd, &ps);
// DrawText (hdc, TEXT ("Hello Windows CE!"), -1, &rect,
// DT_CENTER | DT_VCENTER | DT_SINGLELINE);
DrawText (hdc, pszText, -1, &rect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, 20, 20);
HBITMAP hOldMemBmp = (HBITMAP)SelectObject(hdcMem,hBitmap);
HDC hdcBmp = CreateCompatibleDC(hdc);
HANDLE hBmpDis = LoadImage(hInst,MAKEINTRESOURCE(IDB_BITMAP), IMAGE_BITMAP, 0, 0, 0);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hdcBmp,hBmpDis);
BitBlt(hdcMem, 0, 0, 20, 20, hdcBmp, 0, 0, SRCCOPY);
BitBlt(hdc, 0, 0, 20, 20, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcBmp,hOldBmp);
SelectObject(hdcMem,hOldMemBmp);
DeleteObject(hBitmap);
DeleteDC(hdcMem);
DeleteDC(hdcBmp);
EndPaint (hWnd, &ps);
return 0;
}
//----------------------------------------------------------------------
// DoDestroyMain - Process WM_DESTROY message for window.
//
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam)
{
PostQuitMessage (0);
return 0;
}
//----------------------------------------------------------------------
// DoLButtonDownMain - Process WM_LBUTTONDOWN message for window.
//
LRESULT DoLButtonDownMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam)
{
POINT pt;
int rc;
// Display the menu at the point of the tap
pt.x = LOWORD (lParam);
pt.y = HIWORD (lParam);
SHRGINFO sri;
sri.cbSize = sizeof (sri);
sri.dwFlags = 1;
sri.hwndClient = hWnd;
sri.ptDown = pt;
// See if tap and hold
rc = SHRecognizeGesture (&sri);
if (rc == 0) return 0;
// Display the menu at the point of the tap
ShowContextMenu (hWnd, pt);
return 0;
}
//----------------------------------------------------------------------
// ShowContextMenu - Display a context menu
//
int ShowContextMenu (HWND hWnd, POINT pt) {
HMENU hMenuMain, hMenu;
// Display the menu at the point of the tap
MapWindowPoints (hWnd, HWND_DESKTOP, &pt, 1);
pt.x += 5;
hMenuMain = LoadMenu (hInst, MAKEINTRESOURCE (ID_MENU));
hMenu = GetSubMenu (hMenuMain, 0);
TPMPARAMS tpm;
tpm.cbSize = sizeof (tpm);
GetClientRect (hWnd, &tpm.rcExclude);
TrackPopupMenuEx (hMenu, TPM_LEFTALIGN | TPM_TOPALIGN,
pt.x, pt.y, hWnd, &tpm);
DestroyMenu (hMenuMain);
DestroyMenu (hMenu);
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandExit - Process Program Exit command.
//
LPARAM DoMainCommandExit (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode)
{
SendMessage (hWnd, WM_CLOSE, 0, 0);
return 0;
}
//----------------------------------------------------------------------
// DoCommandMain - Process WM_COMMAND message for window.
//
LRESULT DoCommandMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam)
{
WORD idItem, wNotifyCode;
HWND hwndCtl;
int i;
// Parse the parameters.
idItem = (WORD) LOWORD (wParam);
wNotifyCode = (WORD) HIWORD(wParam);
hwndCtl = (HWND) lParam;
// Call routine to handle control message.
for (i = 0; i < dim(MainCommandItems); i++) {
if (idItem == MainCommandItems[i].Code)
return (*MainCommandItems[i].Fxn)(hWnd, idItem, hwndCtl,
wNotifyCode);
}
return 0;
}