Windows API 下载本文

enuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { LoadStringA (hInstance, IDS_APPNAME, (char *) szAppName, sizeof (szAppName)) ; LoadStringA (hInstance, IDS_ERRMSG, (char *) szErrMsg, sizeof (szErrMsg)) ; MessageBoxA (NULL, (char *) szErrMsg, (char *) szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, szCaption, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static char * pText ; static HGLOBAL hResource ; static HWND hScroll ; static int iPosition, cxChar, cyCCCCCCCCClient, iNumLines, xScroll ; HDC hdc ; PAINTSTRUCT ps ; RECT rect ; TEXTMETRIC tm ; switch (message) { case WM_CREATE : hdc = GetDC (hwnd) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cyCCCC = tm.tmHeight + tm.tmExternalLeading ; ReleaseDC (hwnd, hdc) ; xScroll = GetSystemMetrics (SM_CXVSCROLL) ; hScroll = CreateWindow (TEXT ("scrollbar"), NULL, WS_CHILD | WS_VISIBLE | SBS_VERT, 0, 0,,,,,,,, hwnd, (HMENU) 1, hInst, NULL) ; hResource = LoadResource (hInst, FindResource (hInst, TEXT ("AnnabelLee"), TEXT ("TEXT"))) ; pText = (char *) LockResource (hResource) ; iNumLines = 0 ; while (*pText != '\\' && *pText != '\0') { if (*pText == '\n') iNumLines ++ ; pText = AnsiNext (pText) ; } *pText = '\0' ; SetScrollRange (hScroll, SB_CTL, 0, iNumLines, FALSE) ; SetScrollPos (hScroll, SB_CTL, 0

0, FALSE) ; return 0 ; case WM_SIZE : MoveWindow (hScroll, LOWORD (lParam) - xScroll, 0, xScroll, cyClient = HIWORD (lParam), TRUE) ; SetFocus (hwnd) ; return 0 ; case WM_SETFOCUS : SetFocus (hScroll) ; return 0 ; case WM_VSCROLL : switch (wParam) { case SB_TOP : iPosition = 0 ; break ; case SB_BOTTOM : iPosition = iNumLines ; break ; case SB_LINEUP : iPosition -= 1 ; break ; case SB_LINEDOWN : iPosition += 1 ; break ; case SB_PAGEUP : iPosition -= cyClient / cyChar ; break ; case SB_PAGEDOWN : iPosition += cyClient / cyChar ; break ; case SB_THUMBPOSITION : iPosition = LOWORD (lParam) ; break ; } iPosition = max (0, min (iPosition, iNumLines)) ; if (iPosition != GetScrollPos (hScroll, SB_CTL)) { SetScrollPos (hScroll, SB_CTL, iPosition, TRUE) ; InvalidateRect (hwnd, NULL, TRUE) ; } return 0 ; case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; pText = (char *) LockResource (hResource) ; GetClientRect (hwnd, &rect) ; rect.left += cxChar ; rect.top += cyChar * (1 - iPosition) ; DrawTextA (hdc, pText, -1, &rect, DT_EXTERNALLEADING) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY : FreeResource (hResource) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } POEPOEM.RC (摘录) //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // TEXT ANNABELLEE TEXT DISCARDABLE "poepoem.txt" ///////////////////////////////////////////////////////////////////////////// // Icon POEPOEM ICON DISCARDABLE "poepoem.ico" /////////////////////////////////////////////////////////////////////////////

// String Table STRINGTABLE DISCARDABLE BEGIN IDS_APPNAME "PoePoem" IDS_CAPTION """Annabel Lee"" by Edgar Allan Poe" IDS_ERRMSG "This program requires Windows NT!" END RESOURCE.H (摘录) // Microsoft Developer Studio generated include file. // Used by PoePoem.rc #define IDS_APPNAME 1 #define IDS_CAPTION 2 #define IDS_ERRMSG 3 POEPOEM.TXT It was many and many a year ago, In a kingdom by the sea, That a maiden there lived whom you may know By the name of Annabel Lee; And this maiden she lived with no other thought Than to love and be loved by me. I was a child and she was a child In this kingdom by the sea, But we loved with a love that was more than love -- I and my Annabel Lee -- With a love that the winged seraphs of Heaven Coveted her and me. And this was the reason that, long ago, In this kingdom by the sea, A wind blew out of a cloud, chilling My beautiful Annabel Lee; So that her highborn kinsmen came And bore her away from me, To shut her up in a sepulchre In this kingdom by the sea. The angels, not half so happy in Heaven, Went envying her and me -- Yes! that was the reason (as all men know, In this kingdom by the sea) That the wind came out of the cloud by night, Chilling and killing my Annabel Lee. But our love it was stronger by far than the love Of those who were older than we -- Of many far wiser than we -- And neither the angels in Heaven above Nor the demons down under the sea Can ever dissever my soul from the soul Of the beautiful Annabel Lee: For the moon never beams, without bringing me dreams Of the beautiful Annabel Lee; And the stars never rise, but I feel the bright eyes Of the beautiful Annabel Lee: And so, all the night-tide, I lie down by the side Of my darling -- my darling -- my life and my bride, In her sepulchre there by the sea -- In her tomb by the sounding sea. [May, 1849] \ POEPOEM.ICO 在POEPOEM.RC资源描述档中,使用者定义的资源被定义为TEXT类型,取名为AnnabelLee: ANNABELLEE TEXT POEPOEM.TXT 在WndProc处理WM_CREATE时,使用FindResource和LoadResource取得资源代号。使用LockResource锁定资源,并且使用一个小程序将文件末尾的反斜线(\)换成0,这有利于后面WM_PAINT消息处理期间使用的DrawText函数。 注意,这里使用的是子窗口的卷动列,而不是窗口卷动列,这是因为子窗口卷动列有一个自动的键盘介面,因此在POEPOEM中没有处理WM_KEYDOWN。 POEPOEM还使用三个字符串,它们的ID在RESOURCE.H头文件中定义。在程序的开始,ID

S_APPNAME和IDS_CAPTIONPOEPOEM字符串由LoadString载入内存: LoadString (hInstance, IDS_APPNAME, szAppName, sizeof (szAppName) / sizeof (TCHAR)) ; LoadString (hInstance, IDS_CAPTION, szCaption, sizeof (szCaption) / sizeof (TCHAR)) ; 注意RegisterClass前面的两个调用。如果您在Windows 98下执行Unicode版本的POEPOEM,这两个调用就都会失败。因此,LoadStringA比LoadStringW要复杂得多(LoadStringA必须将资源字符串由Unicode转化为ANSI,而LoadStringW仅是直接载入它),LoadStringW在Windows 98下不被支持。这意味著在Windows 98下,当RegisterClassW函数失败时,MessageBoxW函数(Windows 98支持)就不能使用LoadStringW载入程序的字符串。由于这个原因,程序使用LoadStringA载入IDS_APPNAME和IDS_ERRMSG字符串,并使用MessageBoxA显示自订的消息方块: if (!RegisterClass (&wndclass)) { LoadStringA (hInstance, IDS_APPNAME, (char *) szAppName, sizeof (szAppName)) ; LoadStringA (hInstance, IDS_ERRMSG, (char *) szErrMsg, sizeof (szErrMsg)) ; MessageBoxA (NULL, (char *) szErrMsg, (char *) szAppName, MB_ICONERROR) ; return 0 ; } 注意,TCHAR字符串变量是指向char的指针。 既然我们已经定义了用于POEPOEM的所有字符串资源,那么翻译者将程序转换成外语版本就很容易了。当然,它们将不得不翻译「Annabel Lee」这个名字-我想,这会是一项困难得多的工作。 功能表 您还记得Monty Python有关乳酪店的幽默短剧吗?那故事内容是这样的:一个客人走进乳酪店想买某种乳酪。当然,店里没有这种乳酪。因此他又问有没有另一种乳酪,然后再问另一种,再问另一种,不断的问店家有没有另一种乳酪(最后总共问了40种的乳酪),回答仍然是没有,妹妹妹妹妹,妹妹妹妹有。 这个不幸的事件可以通过功能表的使用来避免。一个功能表是一列可用的选项,它告诉饥饿的用餐者,厨房可以提供哪些服务,并且-对于Windows程序来说-还告诉使用者一个应用程序能够执行哪些操作。 功能表可能是Windows程序提供的一致使用者介面中最重要的部分,而在您的程序中增加功能表,是Windows程序设计中相对简单的部分。您在Developer Studio中定义功能表。每个可选的功能表项被赋予唯一的ID。您在窗口类别结构中指定功能表名称。当使用者选择一个功能表项时,Windows给您的程序发送包含该ID的WM_COMMAND消息。 讨论完功能表后,我还将讨论键盘加速键,它们是一些键的组合,主要用于启动功能表功能。 功能表