C++——Windows 程序开发

       开发 Windows API的Windows程序,需要编写两个函数。一个是Winmain()函数,程序的执行从这里开始,基本的初始化工作也在这里完成。另一个是WindowProc()函数,该函数由Windows调用,用来给应用程序传递消息。Winmain与WindowProc函数通过调用系统的API与Windows通信,如图所示:

C++——Windows 程序开发_第1张图片

1 Winmain函数

Winmain()函数等价于控制台的程序中的main()函数,Winmain()函数的原型如下:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow);

   (1) WINAPI是一个Windows定义的宏,将使系统以特定于Windows API函数的特种方式处理函数名和实参。

   (2) hInstance是指向某个实例的的句柄。

   (3) hPrevInstance是16位操作系统继承下来的,现在的操作系统可以将这位始终设为空。

   (4) lpCmdLine是指向某个字符串的指针,该字符串包括启动程序的命令行字符。

   (5) nCmdShow决定着被创建窗口的外观。

程序中的Winmain()函数需要做以下四件事情:

   (1) 指定程序窗口种类

   (2) 创建窗口

   (3) 初始化窗口

   (4) 处理部分消息

1.1 指定程序窗口

Windows使用WNDCLASSEX来包含用来指定窗口的数据,WNDCLASSEX 结构用于注册窗口类,WNDCLASSEX的结构定义如下:

struct WNDCLASSEX {

UINT cbSize;                           // WNDCLASSEX 的大小

UINT style;                              //窗口类的样式,它的值可以是窗口样式值的任意组合

WNDPROC lpfnWndProc;      //指向窗口处理消息的函数的指针

int cbClsExtra;                        //允许请求Windows在内部为特别用途提供额外空间,常用初始化为0

int cbWndExtra;                     //允许请求Windows在内部为特别用途提供额外空间,常用初始化为0

HINSTANCE hInstance;        //当前应用程序的实例句柄

HICON hIcon;                       //最小化时的应用程序

HCURSOR hCursor;            //窗口使用的光标

HBRUSH hbrBackground;   //窗口客户区的背景色

LPCTSTR lpszMenuName;  //定义窗口菜单的资源名称;如果窗口没有菜单,则定义为NULL

LPCTSTR lpszClassName;  //指向窗口类的指针,LPSTR类型

HICON hIconSm;                 //小图标的句柄,在任务栏显示的图标

};

1.2 创建程序窗口

将WNDCLASSEX结构的所有成员都设置为所需的值后,下一步是把相关情况告诉Windows。使用RegisterClassEx()来完成这件事。假定WNDCLASSEX的对象是WindowsClass,则相应的语句如下所示:

RegisterClassEx(&WindowsClass);//注册窗口类

接下来是创建窗口,由createWindow()函数完成。

HWND hWnd;                                       //窗体句柄

 hWnd = CreateWindow(
    szAppName,                                                 // the window class name
    _T("A Basic Window the Hard Way"),          //标题栏文本
    WS_OVERLAPPEDWINDOW,                    // 创建后的窗体样式
    CW_USEDEFAULT,                                     // 窗体位置
    CW_USEDEFAULT,                                     // 左上角位置坐标
    CW_USEDEFAULT,                                     // 窗体长度
    CW_USEDEFAULT,                                     // 窗体高度
    nullptr,                                     // 如果不是父窗体设置为空
    nullptr,                                     // 没有菜单设置为空
    hInstance,                                   // Program Instance handle
    nullptr                                      // No window creation data
    );

在调用CreateWindow()函数后,被创建的窗口现在已经存在,但是还没有显示在屏幕上。需要调用另一个Windows API函数将该窗口显示出来:

 ShowWindow(hWnd, nCmdShow); 

第一个参数是CreateWindow()函数返回的句柄。第二个参数是给Winmain()传递的nCmdShow值,它指出在屏幕显示窗口的方式。

1.3 初始化程序窗口

在调用 ShowWindow()函数后,该窗口将出现在屏幕上,但仍然没有应用程序的内容。绘制工作区的最好方法是把绘制工作区的代码放入WindowProc()函数,并使Windows给程序发送请求重画工作区的消息。调用另一个Windows API函数UpdateWindow(),请求Windows给程序发送一条重画窗口工作区的消息。调用该函数的窗口如下:

UpdateWindow(hwnd);

1.4 处理Windows消息

Windows有两种消息:一种是排队消息,Winmain()从队列中提取这些消息进行处理,称为消息循环;另一种是致使Windows直接调用WindowsProc()函数的非排队消息。我们在Winmain()函数的消息循环中所作的事情是从Windows为应用程序排好的消息队列中提取一条消息,然后请求Windows调用WindowsProc()函数来处理该消息。

while (GetMessage(&msg, nullptr, 0, 0) == TRUE) // Get any messages
  {
    TranslateMessage(&msg);                      // Translate the message
    DispatchMessage(&msg);                       // Dispatch the message
  }
  • GetMessage()——从队列中检索一条消息
  • TranslateMessage()——对检索的消息执行必要的转换
  • DispatchMessage()——使Windows调用应用程序的WindowProc()函数来处理消息

2 处理Windows消息

使Windows以我们希望的方式运行的所有代码都在程序的消息处理部分——WindowProc()函数

2.1 WindowProc()函数

WindowProc()函数的原型如下:

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam);

可以使用WINAPI替代CALLBACK,但后者更好地表达出这个函数的作用。每个参数的意义如下:
HWND hWnd : 一个句柄,事件引起消息发生的窗口
UINT message: 消息的ID,指出消息类型的32为整数值
WPARAM wParam : 32位值,包含附加信息,决定于消息的种类
LPARAM lParam: 32位值

2.2 解码Windows消息

switch (message)                               // Process selected messages
  {
  case WM_PAINT:    

  //绘制窗口工作区的代码

   break;

case WM_LBUTTONDOWN:

//处理鼠标左键按下时的事件

break;

case WM_LBUTTONUP:

  //处理鼠标释放时的事件

 break;

......

case WM_DESTROY:                               // Window is being destroyed
   //退出窗口
 break;

default:

//其他默认语句

}

3 完整程序代码

#include 
#include 

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,
  WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  LPSTR lpCmdLine, int nCmdShow)
{
  WNDCLASSEX WindowClass;                        // Structure to hold our window's attributes

  static LPCTSTR szAppName { _T("OFWin") };      // Define window class name
  HWND hWnd;                                     // Window handle
  MSG msg;                                       // Windows message structure

  WindowClass.cbSize = sizeof(WNDCLASSEX);       // Set structure size

  // Redraw the window if the size changes
  WindowClass.style = CS_HREDRAW | CS_VREDRAW;

  // Define the message handling function
  WindowClass.lpfnWndProc = WindowProc;

  WindowClass.cbClsExtra = 0;                    // No extra bytes after the window class
  WindowClass.cbWndExtra = 0;                    // structure or the window instance

  WindowClass.hInstance = hInstance;             // Application instance handle

  // Set default application icon
  WindowClass.hIcon = LoadIcon(nullptr, IDI_APPLICATION);

  // Set window cursor to be the standard arrow
  WindowClass.hCursor = LoadCursor(nullptr, IDC_ARROW);

  // Set gray brush for background color
  WindowClass.hbrBackground = static_cast(GetStockObject(GRAY_BRUSH));

  WindowClass.lpszMenuName = nullptr;            // No menu
  WindowClass.lpszClassName = szAppName;         // Set class name
  WindowClass.hIconSm = nullptr;                 // Default small icon

  // Now register our window class
  RegisterClassEx(&WindowClass);

  // Now we can create the window
  hWnd = CreateWindow(
    szAppName,                                   // the window class name
    _T("A Basic Window the Hard Way"),           // The window title
    WS_OVERLAPPEDWINDOW,                         // Window style as overlapped
    CW_USEDEFAULT,                               // Default screen position of upper left
    CW_USEDEFAULT,                               // corner of our window as x,y.
    CW_USEDEFAULT,                               // Default window size width ...
    CW_USEDEFAULT,                               // ... and height
    nullptr,                                     // No parent window
    nullptr,                                     // No menu
    hInstance,                                   // Program Instance handle
    nullptr                                      // No window creation data
    );

  ShowWindow(hWnd, nCmdShow);                    // Display the window
  UpdateWindow(hWnd);                            // Redraw window client area 

  // The message loop
  while (GetMessage(&msg, nullptr, 0, 0) == TRUE) // Get any messages
  {
    TranslateMessage(&msg);                      // Translate the message
    DispatchMessage(&msg);                       // Dispatch the message
  }

  return static_cast(msg.wParam);           // End, so return to Windows
}


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,
  WPARAM wParam, LPARAM lParam)
{

  switch (message)                               // Process selected messages
  {
  case WM_PAINT:                                 // Message is to redraw the window
    HDC hDC;
    PAINTSTRUCT PaintSt;                         // Structure defining area to be drawn
    hDC = BeginPaint(hWnd, &PaintSt) ;           // Prepare to draw the window

    // Get upper left and lower right of client area
    RECT aRect;                                  // A working rectangle
    GetClientRect(hWnd, &aRect);

    SetBkMode(hDC, TRANSPARENT);                 // Set text background mode

    // Now draw the text in the window client area
    DrawText(
      hDC,                                       // Device context handle
      _T("But, soft! What light through yonder window breaks?"),
      -1,                                        // Indicate null terminated string
      &aRect,                                    // Rectangle in which text is to be drawn
      DT_SINGLELINE |                            // Text format - single line
      DT_CENTER |                                //             - centered in the line
      DT_VCENTER);                               //             - line centered in aRect

    EndPaint(hWnd, &PaintSt);                    // Terminate window redraw operation
    return 0;

  case WM_DESTROY:                               // Window is being destroyed
    PostQuitMessage(0);
    return 0;
  }
  return DefWindowProc(hWnd, message, wParam, lParam);
}

你可能感兴趣的:(信息安全,C++,Windows编程)