深入浅出MFC-Win32程序

1、Windows程序运行本质:以事件为驱动、消息为基础!

2、Windows程序事件驱动特性包括消息的产生、获得、分派、判断、处理。

3、Win32 SDK程序开发流程

 

 Windows程序由程序代码+UI资源两大部分组成,2个部分最后以RC编译器整合为一个完整的EXE文件。

UI资源:本质上也是二进制文件,需要借助各种工具产生,以不同的扩展名存在如.ico .bmp .cur等。程序员需要在资源描述文件(.rc)中描述它们,RC编译器读取RC文件的描述后将所有UI资源文件集中生成一个.RES文件,再与程序代码结合生成EXE可执行文件。

4、Windows程序依赖的函数库(.LIB)

  Windows程序调用的函数分为C Runtime以及Windows API两部分:

  • LIBC.LIB 是C Runtime函数库的静态链接版本。
  • MSVCRT.LIB 是C Runtime的动态链接版本(MSVCRT40.DLL)的Import库,链接此函数库程序执行时必须有MSVCRT40.DLL。
  • Windows API部分由Windows操作系统本身提供,主要是Windows的三大模块GDI32.DLL、USER32.DLL、KERNEL32.DLL。虽然它们都是在运行时链接,但是链接器在程序链接过程中必须知道函数的一些信息,才能够帮助程序在运行时顺利跳转到DLL执行。而这些函数相关的信息就存放在所谓的import库中,即GDI32.LIB USER32.LIB KERNEL32.LIB。(自己编写或第三方的动态库,通过隐式加载的方式时,都需要其对应的导入库即.lib文件和头文件;通过显式加载即LoadLibrary的方式则不需要)

5、需要的头文件

所有Windows程序都必须包含Windows.h,但是它一般只包含三大模块里面的API函数,如果需要使用其他系统DLL,则还需要包含其对应头文件。

6、消息为基础、事件为驱动

 

 

 

 

 7、makefile

 

 

 

 8、一个Win32程序

 

 

# filename : generic.mak
# make file for generic.exe (Generic Windows Application)
# usage : nmake generic.mak (Microsoft C/C++ 9.00) (Visual C++ 2.0)
# usage : nmake generic.mak (Microsoft C/C++ 10.00) (Visual C++ 4.0)

all: generic.exe

generic.res : generic.rc generic.h
    rc generic.rc

generic.obj : generic.c generic.h
    cl -c -W3 -Gz -D_X86_ -DWIN32 generic.c

generic.exe : generic.obj generic.res
    link /MACHINE:I386 -subsystem:windows generic.res generic.obj \
         libc.lib kernel32.lib user32.lib gdi32.lib
//---------------------------------------------------------------------
// 檔名     : generic.h
//---------------------------------------------------------------------
BOOL InitApplication(HANDLE);
BOOL InitInstance(HANDLE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
//---------------------------------------------------------------------
//           Generic - 示範 Win32 程式的基礎寫法
//                   Top Studio * J.J.Hou
// 檔名     : generic.c
// 作者     : 侯俊傑
// 編譯聯結 : 請參考 generic.mak
//---------------------------------------------------------------------

#include <windows.h>   // Windows程序依赖的头文件
#include "resource.h"  // 内部包含各个资源的资源ID
#include "generic.h"   // 本程式头文件

HINSTANCE _hInst;      // Instance handle
HWND      _hWnd;

char _szAppName[] = "Generic";    // 程序名称
char _szTitle[]   = "Generic Sample Application"; // 窗口标题

//---------------------------------------------------------------------
// WinMain - Windows程式入口函数
//---------------------------------------------------------------------
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine,     int nCmdShow)
{
MSG msg;

  UNREFERENCED_PARAMETER(lpCmdLine);      // 避免编译器警告

  if (!hPrevInstance)
      if (!InitApplication(hInstance))
          return (FALSE);

  if (!InitInstance(hInstance, nCmdShow))
      return (FALSE);

  while (GetMessage(&msg, NULL, 0, 0)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
  }

  return (msg.wParam); // 返回 PostQuitMessage 的参数
}
//---------------------------------------------------------------------
// InitApplication - 注册窗口类
//---------------------------------------------------------------------
BOOL InitApplication(HINSTANCE hInstance)
{
WNDCLASS  wc;

  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc   = (WNDPROC)WndProc;     // 注册窗口过程函数
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = 0;
  wc.hInstance     = hInstance;
  wc.hIcon         = LoadIcon(hInstance, "jjhouricon");
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = GetStockObject(WHITE_BRUSH);  // 窗口背景颜色
  wc.lpszMenuName  = "GenericMenu";                // .RC中定义的菜单
  wc.lpszClassName = _szAppName;

  return (RegisterClass(&wc));
}
//---------------------------------------------------------------------
// InitInstance - 产生窗口
//---------------------------------------------------------------------
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
  _hInst = hInstance; 

  _hWnd = CreateWindow(
                       _szAppName,
                       _szTitle,
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       NULL,
                       NULL,
                       hInstance,
                       NULL
                      );

  if (!_hWnd)
      return (FALSE);

  ShowWindow(_hWnd, nCmdShow); // 显式窗口
  UpdateWindow(_hWnd);         // 发送 WM_PAINT 消息
  return (TRUE);
}
//---------------------------------------------------------------------
// WndProc - 窗口过程函数定义
//---------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd,     UINT message,
                         WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;

  switch (message) {
    case WM_COMMAND:

         wmId    = LOWORD(wParam);
         wmEvent = HIWORD(wParam);

         switch (wmId) {
           case IDM_ABOUT:
                DialogBox(_hInst,         // WinMain的第一个参数,当前运用程序实例句柄
                          "AboutBox",     // 对话框资源名称
                          hWnd,           // 父窗口句柄
                          (DLGPROC)About  // 对话框的窗口函数
                         );
                break;

           case IDM_EXIT:
                // 使用者想结束程序,处理方式与 WM_CLOSE 相同。
                DestroyWindow (hWnd);
                break;

           default:
                return (DefWindowProc(hWnd, message, wParam, lParam));
         }
         break;

    case WM_DESTROY:  // 窗口已经被销毁,程序即将结束
         PostQuitMessage(0);
         break;

    default:
         return (DefWindowProc(hWnd, message, wParam, lParam));
  }
  return (0);
}
//---------------------------------------------------------------------
// About - 关于对话框的窗口过程函数
//---------------------------------------------------------------------
LRESULT CALLBACK About(HWND hDlg,     UINT message,
                       WPARAM wParam, LPARAM lParam)
{
  UNREFERENCED_PARAMETER(lParam);      

  switch (message) {
    case WM_INITDIALOG:
         return (TRUE);      // 返回 TRUE 表示已经处理该消息,不需要再处理

    case WM_COMMAND:
         if (LOWORD(wParam) == IDOK
             || LOWORD(wParam) == IDCANCEL) {
             EndDialog(hDlg, TRUE);
             return (TRUE);  // 返回 TRUE 表示已经处理该消息
         }
         break;
  }
  return (FALSE); // FALSE 表示我没有处理这个消息
}
//------------------------ end of file ------------------------------
//---------------------------------------------------------------------
// 文件名: resource.h
//---------------------------------------------------------------------
#define IDM_NEW                         40001
#define IDM_OPEN                        40002
#define IDM_SAVE                        40003
#define IDM_SAVEAS                      40004
#define IDM_PRINT                       40005
#define IDM_PRINTSETUP                  40006
#define IDM_EXIT                        40007
#define IDM_UNDO                        40008
#define IDM_CUT                         40009
#define IDM_COPY                        40010
#define IDM_PASTE                       40011
#define IDM_LINK                        40012
#define IDM_LINKS                       40013
#define IDM_HELPCONTENTS                40014
#define IDM_HELPSEARCH                  40015
#define IDM_HELPHELP                    40016
#define IDM_ABOUT                       40017
//---------------------------------------------------------------------
// 文件名: generic.rc
//---------------------------------------------------------------------
#include "windows.h"
#include "resource.h"

jjhouricon ICON    DISCARDABLE     "jjhour.ico"

GenericMenu MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&New",              IDM_NEW, GRAYED
        MENUITEM "&Open...",          IDM_OPEN, GRAYED
        MENUITEM "&Save",             IDM_SAVE, GRAYED
        MENUITEM "Save &As...",       IDM_SAVEAS, GRAYED
        MENUITEM SEPARATOR
        MENUITEM "&Print...",         IDM_PRINT, GRAYED
        MENUITEM "P&rint Setup...",   IDM_PRINTSETUP, GRAYED
        MENUITEM SEPARATOR
        MENUITEM "E&xit",             IDM_EXIT
    END
    POPUP "&Edit"
    BEGIN
        MENUITEM "&Undo\tCtrl+Z",     IDM_UNDO, GRAYED
        MENUITEM SEPARATOR
        MENUITEM "Cu&t\tCtrl+X",      IDM_CUT, GRAYED
        MENUITEM "&Copy\tCtrl+C",     IDM_COPY, GRAYED
        MENUITEM "&Paste\tCtrl+V",    IDM_PASTE, GRAYED
        MENUITEM "Paste &Link",       IDM_LINK, GRAYED
        MENUITEM SEPARATOR
        MENUITEM "Lin&ks...",         IDM_LINKS, GRAYED
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&Contents",               IDM_HELPCONTENTS, GRAYED
        MENUITEM "&Search for Help On...",  IDM_HELPSEARCH, GRAYED
        MENUITEM "&How to Use Help",        IDM_HELPHELP, GRAYED
        MENUITEM SEPARATOR
        MENUITEM "&About Generic...",       IDM_ABOUT
    END
END

AboutBox DIALOG DISCARDABLE  22, 17, 144, 75
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About Generic"
BEGIN
    CTEXT           "Windows 95",         -1,0, 5,144,8
    CTEXT           "Generic Application",-1,0,14,144,8
    CTEXT           "Version 1.0",        -1,0,34,144,8
    DEFPUSHBUTTON   "OK",              IDOK,53,59,32,14,WS_GROUP
END

WinMain函数是Windows程序的入口点,当使用者执行一个Windows程序时,Windows的Shell进程会调用加载器把该程序加载到进程地址空间,然后调用C Startup Code,C启动代码将调用WinMain函数开始执行程序,WinMain函数的四个参数由操作系统传递。

9、窗口类的注册与窗口的产生

 未完,待更新。。。

posted @ 2021-03-01 17:03  碎银三二两  阅读(279)  评论(0编辑  收藏  举报