在下面的DOIView示例程序中,演示了资源、键盘加速键和弹出式菜单的用法。DOIView是Declaration of Independence View的缩写,显示了美国独立宣言。程序中的文本被存储为一系列字符串资源。DOIView将文本格式化来适应程序窗口,并使用滚动条来滚动文本。
图4-3显示了DOIView窗口。按Ctr-H和Ctr-E可以将文档滚动到开头和结尾。您也可以在窗口上点压来显示一个快捷菜单,用来快速滚动到文档开头、结尾以及结束程序。
图4-3(略):显示快捷菜单的DOI View窗口
DOIView的源文件显示在清单4-2中。请注意第3个包含文件DOIView.rc,它包含了程序的资源脚本。DOIView.rc包含有菜单资源,包含一行程序使用的图标,还包含一个字符串表,里面是用来显示的文字。因为字符串资源被限制为4092个字符,所以文字被包含在多个字符串里。
清单4-2:DOIView 程序
DOIView.rc
//======================================================================
// DOIView - Resource file
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//
//======================================================================
#include "DOIView.h"
//----------------------------------------------------------------------
// Icon
//
ID_ICON ICON "DOIView.ico"
//----------------------------------------------------------------------
// Menu
//
ID_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Goto Start/tCtrl-H", IDM_HOME
MENUITEM "&Goto End/tCtrl-E", IDM_END
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
END
END
//----------------------------------------------------------------------
// Accelerator table
//
ID_ACCEL ACCELERATORS DISCARDABLE
BEGIN
"H", IDM_HOME, VIRTKEY, CONTROL
"E", IDM_END, VIRTKEY, CONTROL
END
//----------------------------------------------------------------------
// String table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DOITEXT, "IN CONGRESS, July 4, 1776./012The unanimous /
Declaration of the thirteen united States of America,/012WHEN in the /
Course of human Events, it becomes necessary for one People to /
dissolve the Political Bands which have connected them with another, /
and to assume among the Powers of the Earth, the separate and equal /
Station to which the Laws of Nature and of Nature's God entitle them, /
a decent Respect to the Opinions of Mankind requires that they should /
declare the causes which impel them to the Separation./012/
WE hold these Truths to be self-evident, that all Men are created /
equal, that they are endowed by their Creator with certain /
unalienable Rights, that among these are Life, Liberty and the Pursuit /
of Happiness -- That to secure these Rights, Governments are /
instituted among Men, deriving their just Powers from the Consent of /
the Governed, that whenever any Form of Government becomes destructive /
of these Ends, it is the Right of the People to alter or to abolish /
it, and to institute new Government, laying its Foundation on such /
Principles, and organizing its Powers in such Form, as to them shall /
seem most likely to effect their Safety and Happiness. Prudence, /
indeed, will dictate that Governments long established should /
not be changed for light and transient Causes; and accordingly all /
Experience hath shewn, that Mankind are more disposed to suffer, while /
Evils are sufferable, than to right themselves by abolishing the Forms /
to which they are accustomed. But when a long Train of Abuses and /
Usurpations, pursuing invariably the same Object, evinces a Design to /
reduce them under absolute Despotism, it is their Right, it is their /
Duty, to throw off such Government, and to provide new Guards for /
their future Security. Such has been the patient Sufferance of these /
Colonies; and /
such is now the Necessity which constrains them to alter their /
former Systems of Government. The History of the present King of Great /
Britain is a History of repeated Injuries and Usurpations, all having /
in direct Object the Establishment of an absolute Tyranny over these /
States. To prove this, let Facts be submitted to a candid World./012/
HE has refused his Assent to Laws, the most wholesome and /
necessary for the public Good./012HE has forbidden his Governors to /
pass Laws of immediate and pressing Importance, unless suspended in /
their Operation till his Assent should be obtained; and when so /
suspended, he has utterly neglected to attend to them./012/
HE has refused to pass other Laws for the Accommodation of large /
Districts of People, unless those People would relinquish the Right of /
Representation in the Legislature, a Right inestimable to them, and /
formidable to Tyrants only./012HE has called together Legislative /
Bodies at Places unusual, uncomfortable, and distant from the /
Depository of their public Records, for the sole Purpose of fatiguing /
them into Compliance with his Measures./012/
HE has dissolved Representative Houses repeatedly, for opposing /
with manly Firmness his Invasions on the Rights of the People./012HE /
has refused for a long Time, after such Dissolutions, to cause others /
to be elected; whereby the Legislative Powers, incapable of the /
Annihilation, have returned to the People at large for their exercise; /
the State remaining in the mean time exposed to all the Dangers of /
Invasion from without, and the Convulsions within./012/
HE has endeavoured to prevent the Population of these States; /
for that Purpose obstructing the Laws for Naturalization of Foreigners/
; refusing to pass others to encourage their Migrations hither, and /
raising the Conditions of new Appropriations of Lands./012HE has /
obstructed the Administration of Justice, by refusing his Assent to /
Laws for establishing Judiciary Powers./012HE has made Judges /
dependent on his Will alone, for the Tenure of their Offices, and the /
Amount and Payment of their Salaries./012"
IDS_DOITEXT1, "HE has erected a Multitude of new Offices, and sent /
hither Swarms of Officers to harrass our People, and eat out their /
Substance./012HE has kept among us, in Times of Peace, Standing /
Armies, without the consent of our Legislatures./012HE has affected to /
render the Military independent of and superior to the Civil Power./012/
HE has combined with others to subject us to a Jurisdiction /
foreign to our Constitution, and unacknowledged by our Laws; giving /
his Assent to their Acts of pretended Legislation:/012FOR quartering /
large Bodies of Armed Troops among us;/012FOR protecting them, by a /
mock Trial, from Punishment for any Murders which they should commit /
on the Inhabitants of these States:/012FOR cutting off our Trade with /
all Parts of the World:/012/
FOR imposing Taxes on us without our Consent:/012FOR depriving /
us, in many Cases, of the Benefits of Trial by Jury:/012FOR /
transporting us beyond Seas to be tried for pretended Offences:/012/
FOR abolishing the free System of English Laws in a neighbouring /
Province, establishing therein an arbitrary Government, and enlarging /
its Boundaries, so as to render it at once an Example and fit /
Instrument for introducing the same absolute Rules into these /
Colonies:/012/
FOR taking away our Charters, abolishing our most valuable Laws, /
and altering fundamentally the Forms of our Governments:/012FOR /
suspending our own Legislatures, and declaring themselves invested /
with Power to legislate for us in all Cases whatsoever./012HE has /
abdicated Government here, by declaring us out of his Protection and /
waging War against us./012HE has plundered our Seas, ravaged our /
Coasts, burnt our Towns, and destroyed the Lives of our People./012/
HE is, at this Time, transporting large Armies of foreign /
Mercenaries to compleat the Works of Death, Desolation, and Tyranny, /
already begun with circumstances of Cruelty and Perfidy, scarcely /
paralleled in the most barbarous Ages, and totally unworthy the Head /
of a civilized Nation./012HE has constrained our fellow Citizens taken /
Captive on the high Seas to bear Arms against their Country, to become /
the Executioners of their Friends and Brethren, or to fall themselves /
by their Hands./012/
HE has excited domestic Insurrections amongst us, and has /
endeavoured to bring on the Inhabitants of our Frontiers, the /
merciless Indian Savages, whose known Rule of Warfare, is an /
undistinguished Destruction, of all Ages, Sexes and Conditions./012IN /
every stage of these Oppressions we have Petitioned for Redress in the /
most humble Terms: Our repeated Petitions have been answered only by /
repeated Injury. A Prince, whose Character is thus marked by every act /
which may define a Tyrant, is unfit to be the Ruler of a free People. /
NOR have we been wanting in Attentions to our Brittish Brethren. /
We have warned them from Time to Time of Attempts by their Legislature /
to extend an unwarrantable Jurisdiction over us. We have reminded them /
of the Circumstances of our Emigration and Settlement here. We have /
appealed to their native Justice and Magnanimity, and we have conjured /
them by the Ties of our common Kindred to disavow these Usurpations, /
which, would inevitably interrupt our Connections and Correspondence. /
They too have been deaf to the Voice of Justice and of Consanguinity. /
We must, therefore, acquiesce in the Necessity, which denounces our /
Separation, and hold them, as we hold the rest of Mankind, Enemies in /
War, in Peace, Friends./012"
IDS_DOITEXT2, "WE, therefore, the Representatives of the UNITED /
STATES OF AMERICA, in GENERAL CONGRESS, Assembled, appealing to the /
Supreme Judge of the World for the Rectitude of our Intentions, do, in /
the Name, and by Authority of the good People of these Colonies, /
solemnly Publish and Declare, That these United Colonies are, and of /
Right ought to be, FREE AND INDEPENDENT STATES; that they are absolved /
from all Allegiance to the British Crown, and that all political /
Connection between them and the State of Great-Britain, is and ought /
to be totally dissolved; and that as FREE AND INDEPENDENT STATES, they /
have full Power to levy War, conclude Peace, contract Alliances, /
establish Commerce, and to do all other Acts and Things which /
INDEPENDENT STATES may of right do. And for the support of this /
Declaration, with a firm Reliance on the Protection of divine /
Providence, we mutually pledge to each other our Lives, our Fortunes, /
and our sacred Honor."
END
DOIView.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
};
#define ID_MENU 10
#define ID_ACCEL 11
#define IDM_HOME 100
#define IDM_END 101
#define IDM_EXIT 102
#define IDS_DOITEXT 1000 // These IDs must be
#define IDS_DOITEXT1 1001 // consecutive
#define IDS_DOITEXT2 1002
//----------------------------------------------------------------------
// Function prototypes
//
LPTSTR WrapString (HDC hdc, LPTSTR pszText, int *pnLen, int nWidth,
BOOL *fEOL);
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 DoSizeMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoCommandMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoLButtonDownMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoRButtonUpMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoVScrollMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoPaintMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);
// Command functions
LPARAM DoMainCommandHome (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandEnd (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandExit (HWND, WORD, HWND, WORD);
DOIView.cpp
//======================================================================
// DOIView - Demonstrates window scroll bars
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include "DOIView.h" // Program-specific stuff
#include <aygshell.h> // Extended shell API
//----------------------------------------------------------------------
// Global data
//
const TCHAR szAppName[] = TEXT("DOIView");
HINSTANCE hInst; // Program instance handle
#define WM_MYMSG (WM_USER + 100)
// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] = {
WM_CREATE, DoCreateMain,
WM_SIZE, DoSizeMain,
WM_LBUTTONDOWN, DoLButtonDownMain,
WM_COMMAND, DoCommandMain,
WM_VSCROLL, DoVScrollMain,
WM_PAINT, DoPaintMain,
WM_DESTROY, DoDestroyMain,
};
// Command Message dispatch for MainWindowProc
const struct decodeCMD MainCommandItems[] = {
IDM_HOME, DoMainCommandHome,
IDM_END, DoMainCommandEnd,
IDM_EXIT, DoMainCommandExit,
};
typedef struct {
LPTSTR pszLine;
int nLen;
} LINEARRAY, *PLINEARRAY;
#define MAXLINES 1000
LINEARRAY laText[MAXLINES];
int nNumLines = 0;
int nFontHeight = 1;
int nLinesPerPage = 1;
LPTSTR pszDeclaration;
HFONT hFont;
int nVPos, nVMax;
BOOL fFirst = TRUE;
//======================================================================
// Program entry point
//
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
MSG msg;
int rc = 0;
HWND hwndMain;
HACCEL hAccel;
// Initialize this instance.
hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);
if (hwndMain == 0) return 0x10;
// Load accelerator table.
hAccel = LoadAccelerators (hInst, MAKEINTRESOURCE (ID_ACCEL));
// Application message loop
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) {
WNDCLASS wc;
HWND hWnd;
PBYTE pRes, pBuff;
int nStrLen = 0, i = 0;
// Save program instance handle in global variable.
hInst = hInstance;
#if defined(WIN32_PLATFORM_PSPC)
// If Pocket PC, only allow one instance of the application
hWnd = FindWindow (szAppName, NULL);
if (hWnd) {
SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));
return 0;
}
#endif
// Load text from multiple string resources into one large buffer
pBuff = (PBYTE)LocalAlloc (LPTR, 8);
while (pRes = (PBYTE)LoadString (hInst, IDS_DOITEXT + 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');
pszDeclaration = (LPTSTR)pBuff;
// 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;
// Create main window.
hWnd = CreateWindowEx (WS_EX_NODRAG, szAppName,
TEXT("The Declaration of Independence"),
WS_VSCROLL | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL,
NULL, hInstance, NULL);
if (!IsWindow (hWnd)) return 0; // Fail code if not created.
// Standard show and update calls
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return hWnd;
}