一个具体而微的Win32程序

许多相关书籍或文章尝试以各种方式简化Windows程序的第一步,因为单单一个Hello程序就要上百行,怕把大家吓坏了。我却宁愿各位早一点接触正统写法,早一点看到全貌。Windows 的东西又多又杂,早一点一窥全貌是很有必要的。而且你会发现,经过有 条理的解释之后,程序代码的多寡其实构不成什么威胁(否则无字天书最适合程序员阅读)。再说,上百进程序代码哪算得了什么!

你可以从图1-2 得窥  Win32 应用程序的本体与操作系统之间的关系。Win32 程序中最具代表意义的动作已经在该图显示出来,完整的程序代码展示于后。本章后续讨论都围绕着此一程序。

稍后会出现一个makefile。关于makefile的语法,可能已经不再为大家所熟悉了。我想我有必要做个说明。所谓makefile,就是让你能够设定某个文件和某个文件相比——比较其产生日期。由其比较结果来决定要不要做某些你所指定的动作。例如:

generic.res : generic.rc generic.h

rc generic.rc

意思就是拿冒号(:)左边的generic.res和冒号右边的generic.rc generic.h 的文件日期相比。只要右边任一文件比左边的文件更新,就执行下一行所指定的动作。这动作可以是任何命令列动作,本例为rc generic.rc

因此,我们就可以把不同文件间的依存关系做一个整理,以makefile 语法描述,以产生必要的编译、链接动作。makefile 必须以NMAKE.EXEMicrosoft 工具)或MAKE.EXEBorland 工具)处理之,或其它编译器套件所附的同等工具(可能也叫做MAKE.EXE)处理之。

  1-2  Windows 程序的本体与操作系统之间的关系

Generic.mak(请在DOS窗口中执行nmake generic.mak。环境设定请参考 p.224

#0001  # filename : generic.mak

#0002  # make file for generic.exe (Generic Windows Application)

#0003  # usage : nmake generic.mak (Microsoft C/C++ 9.00) (Visual C++ 2.x)

#0004  # usage : nmake generic.mak (Microsoft C/C++ 10.00) (Visual C++ 4.0)

#0005

#0006  all: generic.exe

#0007

#0008  generic.res : generic.rc generic.h

#0009      rc generic.rc

#0010

#0011  generic.obj : generic.c generic.h

#0012      cl-c-W3-Gz-D_X86_-DWIN32 generic.c

#0013

#0014  generic.exe : generic.obj generic.res

#0015      link/MACHINE:I386 -subsystem:windows generic.res generic.obj /

#0016          libc.lib kernel32.lib user32.lib gdi32.lib

Generic.h

#0001  //---------------------------------------------------------------

#0002  // 文件名 : generic.h

#0003  //---------------------------------------------------------------

#0004  BOOL InitApplication(HANDLE);

#0005  BOOL InitInstance(HANDLE, int);

#0006  LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

#0007  LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);

Generic.c(粗体代表Windows API函数或宏)

#0001  //---------------------------------------------------------------

#0002  //             Generic - Win32 程序的基础写法

#0003  //                Top Studio * J.J.Hou

#0004  // 文件名     : generic.c

#0005  // 作者       : 侯俊杰

#0006  // 编译链接   : 请参考 generic.mak

#0007  //---------------------------------------------------------------

#0008

#0009  #include <windows.h>   // 每一个 Windows 程序都需要含入此文件

#0010  #include "resource.h"  // 内含各个 resource IDs

#0011  #include "generic.h" // 本程序之含入文件

#0012

#0013  HINSTANCE _hInst; // Instance handle

#0014  HWND      _hWnd;

#0015

#0016  char _szAppName[] = "Generic"; // 程序名称

#0017  char _szTitle[]= "Generic Sample Application"; // 窗口标题

#0017  char _szTitle[]

#0018

#0019  //---------------------------------------------------------------

#0020  // WinMain - 程序进入点

#0021  //---------------------------------------------------------------

#0022  int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

#0023                       LPSTR lpCmdLine, int nCmdShow)

#0024  {

#0025    MSG msg;

#0026

#0027    UNREFERENCED_PARAMETER(lpCmdLine); // 避免编译时的警告

#0028

#0029    if (!hPrevInstance)

#0030        if (!InitApplication(hInstance))

#0031            return (FALSE);

#0032

#0033    if (!InitInstance(hInstance, nCmdShow))

#0034        return (FALSE);

#0035

#0036    while (GetMessage(&msg, NULL, 0, 0)) {

#0037        TranslateMessage(&msg);

#0038        DispatchMessage(&msg);

#0039    }

#0040

#0041    return (msg.wParam); // 传回 PostQuitMessage 的参数

#0042  }

#0043  //---------------------------------------------------------------

#0044  // InitApplication - 注册窗口类

#0045  //---------------------------------------------------------------

#0046  BOOL InitApplication(HINSTANCE hInstance)

#0047  {

#0048   WNDCLASS  wc;

#0049

#0050   wc.style = CS_HREDRAW | CS_VREDRAW;

#0051   wc.lpfnWndProc= (WNDPROC)WndProc; // 窗口函数

#0052   wc.cbClsExtra= 0;

#0053   wc.cbWndExtra= 0;

#0054   wc.hInstance= hInstance;

#0055   wc.hIcon= LoadIcon(hInstance, "jjhouricon");

#0056   wc.hCursor= LoadCursor(NULL, IDC_ARROW);

#0057   wc.hbrBackground = GetStockObject(WHITE_BRUSH);  // 窗口后台颜色

#0058   wc.lpszMenuName  = "GenericMenu"; // .RC 所定义的窗体

#0059   wc.lpszClassName = _szAppName;

#0060

#0061   return (RegisterClass(&wc));

#0062  }

#0063  //---------------------------------------------------------------

#0064  // InitInstance - 产生窗口

#0065  //---------------------------------------------------------------

#0066  BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

#0067  {

#0068     _hInst = hInstance; // 储存为全局变量,方便使用。

#0069

#0070     _hWnd = CreateWindow(

#0071                            _szAppName,

#0072                            _szTitle,

#0073                            WS_OVERLAPPEDWINDOW,

#0074                            CW_USEDEFAULT,

#0075                            CW_USEDEFAULT,

#0076                            CW_USEDEFAULT,

#0077                            CW_USEDEFAULT,

#0078                            NULL,

#0079                            NULL,

#0080                            hInstance,

#0081                            NULL

#0082                            );

#0083

#0084   if (!_hWnd)

#0085       return (FALSE)

#0086

#0087   ShowWindow(_hWnd, nCmdShow); // 显示窗口

#0088   UpdateWindow(_hWnd); // 送出 WM_PAINT

#0089   return (TRUE);

#0090  }

#0091  //---------------------------------------------------------------

#0092  // WndProc - 窗口函数

#0093  //---------------------------------------------------------------

#0094  LRESULT CALLBACK WndProc(HWND hWnd,     UINT message,

#0095                           WPARAM wParam, LPARAM lParam)

#0096  {

#0097    int wmId, wmEvent;

#0098

#0099    switch (message) {

#0100    case WM_COMMAND:

#0101

#0102        wmId    = LOWORD(wParam);

#0103        wmEvent = HIWORD(wParam);

#0104

#0105        switch (wmId) {

#0106        case IDM_ABOUT:

#0107            DialogBox(_hInst,

#0108                      "AboutBox",// 对话框资源名称

#0109                      hWnd, // 父窗口

#0110                      (DLGPROC)About  // 对话框函数名称

#0111                      );

#0112            break;

#0113

#0114        case IDM_EXIT:    // 使用者想结束程序。处理方式与 WM_CLOSE 相同。

#0116            DestroyWindow(hWnd);

#0117            break;

#0118

#0119        default:

#0120            return (DefWindowProc(hWnd, message, wParam, lParam));

#0121        }

#0122        break;

#0123

#0124     case WM_DESTROY:  // 窗口已经被摧毁 (程序即将结束)

#0125         PostQuitMessage(0);

#0126         break;

#0127

#0128     default:

#0129         return (DefWindowProc(hWnd, message, wParam, lParam));

#0130    }

#0131    return (0);

#0132  }

#0133  //---------------------------------------------------------------

#0134  // About - 对话框函数

#0135  //---------------------------------------------------------------

#0136  LRESULT CALLBACK About(HWND hDlg,     UINT message,

#0137                         WPARAM wParam, LPARAM lParam)

#0138  {

#0139     UNREFERENCED_PARAMETER(lParam); // 避免编译时的警告

#0140

#0141     switch (message) {

#0142         case WM_INITDIALOG:

#0143             return (TRUE); // TRUE 表示我已处理过这个消息

#0144

#0145         case WM_COMMAND:

#0146             if (LOWORD(wParam) == IDOK

#0147                 ||LOWORD(wParam) == IDCANCEL) {

#0148                 EndDialog(hDlg, TRUE);

#0149                 return (TRUE);  // TRUE 表示我已处理过这个消息

#0150             }

#0151             break;

#0152  }

#0153     return (FALSE); // FALSE 表示我没有处理这个消息

#0154  }

Generic.rc

#0001  //---------------------------------------------------------------

#0002  // 文件名 : generic.rc

#0003  //---------------------------------------------------------------

#0004  #include "windows.h"

#0005  #include "resource.h"

#0006

#0007  jjhouricon ICON DISCARDABLE "jjhour.ico"

#0008

#0009  GenericMenu MENU DISCARDABLE

#0010  BEGIN

#0011         POPUP "&File"

#0012         BEGIN

#0013             MENUITEM "&New",             IDM_NEW, GRAYED

#0014             MENUITEM "&Open...",         IDM_OPEN, GRAYED

#0015             MENUITEM "&Save",            IDM_SAVE, GRAYED

#0016             MENUITEM "Save &As...",      IDM_SAVEAS, GRAYED

#0017             MENUITEM SEPARATOR

#0018             MENUITEM "&Print...",        IDM_PRINT, GRAYED

#0019             MENUITEM "P&rint Setup...",  IDM_PRINTSETUP, GRAYED

#0020             MENUITEM SEPARATOR

#0021             MENUITEM "E&xit",            IDM_EXIT

#0022         END

#0023         POPUP "&Edit"

#0024         BEGIN

#0025             MENUITEM "&Undo/tCtrl+Z",    IDM_UNDO, GRAYED

#0026             MENUITEM SEPARATOR

#0027             MENUITEM "Cu&t/tCtrl+X",     IDM_CUT, GRAYED

#0028             MENUITEM "&Copy/tCtrl+C",    IDM_COPY, GRAYED

#0029             MENUITEM "&Paste/tCtrl+V",   IDM_PASTE, GRAYED

#0030             MENUITEM "Paste &Link",      IDM_LINK, GRAYED

#0031             MENUITEM SEPARATOR

#0032             MENUITEM "Lin&ks...",        IDM_LINKS, GRAYED

#0033         END

#0034         POPUP "&Help"

#0035         BEGIN

#0036             MENUITEM "&Contents",               IDM_HELPCONTENTS, GRAYED

#0037             MENUITEM "&Search for Help On...",  IDM_HELPSEARCH, GRAYED

#0038             MENUITEM "&How to Use Help",        IDM_HELPHELP, GRAYED

#0039             MENUITEM SEPARATOR

#0040             MENUITEM "&About Generic...",       IDM_ABOUT

#0041         END

#0042   END

#0043

#0044   AboutBox DIALOG DISCARDABLE  22, 17, 144, 75

#0045   STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU

#0046   CAPTION "About Generic"

#0047   BEGIN

#0048       CTEXT "Windows 95", -1,0, 5,144,8

#0049       CTEXT "Generic Application",-1,0,14,144,8

#0050       CTEXT "Version 1.0",-1,0,34,144,8

#0051       DEFPUSHBUTTON "OK", IDOK,53,59,32,14,WS_GROUP

#0052   END

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值