您的位置:首页 > 编程语言 > C语言/C++

C++下Windows 程序编程

2019-07-15 16:36 1271 查看

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

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 完整程序代码

 

[code]// Ex11_01.cpp   Native windows program to display text in a window
#include <windows.h>
#include <tchar.h>

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

// Listing OFWIN_1
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<HBRUSH>(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<int>(msg.wParam);           // End, so return to Windows
}

// Listing OFWIN_2
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);
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: