
C语言写Windows软件的方法包括:使用WinAPI、利用MFC框架、结合资源文件。WinAPI是最基础的方式,它提供了对Windows操作系统核心功能的访问。下面将详细介绍如何使用WinAPI开发Windows应用程序。
一、WinAPI基础
1、WinAPI概述
Windows API(简称WinAPI)是微软为Windows操作系统提供的一组编程接口。通过WinAPI,开发者可以直接与操作系统进行交互,如创建窗口、处理消息、绘图等。WinAPI是开发Windows应用程序的基础,虽然比较复杂,但非常灵活和强大。
2、Hello World程序
首先,我们从一个简单的Hello World程序开始,它将展示如何创建一个基本的窗口并响应消息。
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
const char CLASS_NAME[] = "Sample Window Class";
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(
0,
CLASS_NAME,
"Hello, Windows!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
if (hwnd == NULL) {
return 0;
}
ShowWindow(hwnd, nCmdShow);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
3、代码解析
WNDCLASS结构体:定义窗口类的属性。WindowProc函数:窗口过程函数,用于处理窗口消息。RegisterClass函数:注册窗口类。CreateWindowEx函数:创建窗口。ShowWindow和UpdateWindow函数:显示和更新窗口。- 消息循环:使用
GetMessage、TranslateMessage、DispatchMessage处理消息。
二、消息处理
1、消息机制
Windows操作系统通过消息机制与应用程序进行交互。每个窗口都有一个消息队列,当用户与窗口交互时(如点击按钮、移动鼠标),这些交互会被转换为消息并放入队列中。窗口过程函数负责处理这些消息。
2、常见消息
WM_DESTROY:窗口销毁消息,当窗口关闭时发送。WM_PAINT:绘图消息,当窗口需要重新绘制时发送。WM_KEYDOWN:键盘按下消息,当用户按下某个键时发送。
3、处理消息
在窗口过程函数中,可以通过switch语句处理不同的消息。例如:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 50, 50, "Hello, Windows!", 15);
EndPaint(hwnd, &ps);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
三、窗口组件
1、按钮
按钮是Windows应用程序中常见的组件之一。可以通过CreateWindowEx函数创建按钮:
HWND hwndButton = CreateWindowEx(
0,
"BUTTON",
"Click Me",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
10,
10,
100,
30,
hwnd,
(HMENU) 1,
(HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
NULL
);
2、处理按钮点击
当按钮被点击时,会发送WM_COMMAND消息。在窗口过程函数中处理该消息:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_COMMAND:
if (LOWORD(wParam) == 1) {
MessageBox(hwnd, "Button Clicked!", "Information", MB_OK);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
四、绘图
1、设备上下文
绘图需要使用设备上下文(Device Context, DC),它代表了绘图表面。可以通过BeginPaint函数获取设备上下文:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
2、基本绘图操作
- 绘制文本:使用
TextOut函数。 - 绘制线条:使用
MoveToEx和LineTo函数。 - 绘制矩形:使用
Rectangle函数。
例如:
TextOut(hdc, 50, 50, "Hello, Windows!", 15);
MoveToEx(hdc, 10, 10, NULL);
LineTo(hdc, 100, 100);
Rectangle(hdc, 20, 20, 80, 80);
3、结束绘图
绘图完成后,需要调用EndPaint函数释放设备上下文:
EndPaint(hwnd, &ps);
五、对话框
1、模态对话框
模态对话框在显示时会阻塞主窗口,直到对话框关闭。例如,使用MessageBox函数显示一个模态对话框:
MessageBox(hwnd, "This is a modal dialog", "Dialog", MB_OK);
2、非模态对话框
非模态对话框不会阻塞主窗口,可以与主窗口同时交互。使用CreateDialog函数创建非模态对话框:
HWND hwndDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, DialogProc);
ShowWindow(hwndDialog, SW_SHOW);
3、处理对话框消息
对话框消息处理函数:
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
六、文件操作
1、打开文件对话框
使用GetOpenFileName函数显示打开文件对话框:
OPENFILENAME ofn;
char szFile[260];
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '