c语言调用api创建窗口,MFC(1):c语言/c++ 纯API 创建窗口 底层原理

Visual Studio直接创建一个空项目

新建一个 后缀为 .c 或者 .cpp文件#include 

//如果出现该符号在函数中被引用需要配置:项目-》属性->配置属性->连接器=》系统  子系统   设置为  窗口 (/SUBSYSTEM:WINDOWS)

//WINAPI代表_stdcall参数的传递顺序,从右到左以此入栈,并且在函数返回前清空堆栈

LRESULT CALLBACK 窗口过程(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM LParam);

//WINAPI代表_stdcall参数的传递顺序,从右到左以此入栈,并且在函数返回前清空堆栈

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

//1.设计窗口

//2.注册窗口

//3.创建窗口

//4.显示和更新

//5通过循环取消息

//6处理消息

//第一步:设计窗口

WNDCLASS wc;

wc.cbClsExtra = 0;//类的额外内存

wc.cbWndExtra = 0;//窗口的额外内存

wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//设置背景

wc.hCursor = LoadCursor(NULL, IDC_HAND);//设置光标 如果第一个参数为null,代表使用系统提供的光标

wc.hIcon = LoadIcon(NULL, IDI_ERROR);//图标,如果第一个参数为null,代表使用系统提供的光标

wc.hInstance = hInstance;//实例句柄 传入形参即可

wc.lpfnWndProc = 窗口过程; //回调函数

wc.lpszClassName = TEXT("win");//窗口类名

wc.lpszMenuName = NULL;//菜单名称

wc.style = CS_HREDRAW;// 0;//0代表默认风格

//第二部:注册窗口类

RegisterClass(&wc);

//第三部:创建窗口(返回之前发送WM_CREATE)

HWND hWndParent = CreateWindow("win","纯API创建窗口",WS_OVERLAPPEDWINDOW,50,50,500,500,NULL,NULL,hInstance,NULL);

//第四部:显示

ShowWindow(hWndParent, SW_SHOWNORMAL);

//更新窗口(发送WM_PAINT)

UpdateWindow(hWndParent);

//第五步:通过循环取消息

//msg结构:

//HWND        hwnd;主窗口句柄

//UINT        message;消息名称

//WPARAM      wParam;附加消息 键盘消息

//LPARAM      lParam;附加消息 鼠标消息(按键消息)

//DWORD       time;消息产生的时间

//POINT       pt;附加消息 鼠标消息(位置xy)

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))//  参数一:消息指针 参数2:null代表捕获所有窗口 3和4 填写0代表捕获所有消息

{

//翻译消息

TranslateMessage(&msg);//翻译消息是为了处理一些组合按键

//分发消息

DispatchMessage(&msg);

}

return true;

}

LRESULT CALLBACK 窗口过程(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM LParam){  //消息所处的窗口句柄,具体消息名称 WM_xxxx消息

switch (uMsg)

{

case WM_CLOSE:

DestroyWindow(hwnd);//销毁窗口 但是不是结束进程,而是发送另一个消息:WM_DESTROY

break;

case WM_DESTROY:

PostQuitMessage(0); //发送退出消息,发完此消息后,在while死循环里 GetMessage() 获取到的就是 false了.就会结束程序!

break;

case WM_LBUTTONDOWN:

{  //如果C语言,需要把这些不在一行的代码括起来.

int x = LOWORD(LParam);

int y = HIWORD(LParam);

char buf[1024];

wsprintf(buf,TEXT("x=%d,y=%d"), x, y);

MessageBox(hwnd, buf, TEXT("鼠标左键被按下"), MB_OK);

break;

}

case WM_PAINT:

{

PAINTSTRUCT ps;//绘图结构体

HDC hdc=BeginPaint(hwnd, &ps);

TextOut(hdc, 100, 100, TEXT("hello"), strlen("hello"));

EndPaint(hwnd,&ps);

break;

}

}

//消息一般都是 WM_开头的,可以从API常量里查询!

/*返回值用默认的处理方式*/

return DefWindowProc(hwnd, uMsg, wParam, LParam);

}

扩展阅读:

窗口类WNDCLASS

窗口类WNDCLASS是是Windows中用于创建窗口的模板。每一个窗口类都有一个窗口过程

(WndProc),负责处理发送该类窗口的所有消息。一个应用程序在创建某个类型的窗口前,必须

首先注册该“窗口类”(注意,这里不是C++类的类)。窗口类有三种:

系统窗口类中一部分是系统内部使用的,而另一部分是可以供系统所有进程使用的,这些窗口类就

是基本的控件窗口类。

应用程序全局窗口类,就是注册窗口类时以CS_GLOBALCLASS标志注册的窗口类,这个窗口类在这

个进程中,所有模块都可以使用。模块一般是dll模块。我们知道的程序的皮肤库,很多都是以这种

形式实现的,dll中注册的应用程序全局窗口类,我们程序就可以直接使用这些漂亮的皮肤库提供的

控件了。

应用程序局部窗口类则是没有CS_GLOBALCLASS标志注册的窗口类,这个窗口类只在模块范围内使

用。我们的EXE如果加载了其他的dl模块,此时EXE的主线程注册的应用程序局部窗口类对于dll来

说,是看不见的,也就不能使用这个局部窗口类来创建窗口。

扩展阅读 如何创建两个窗口,共用一个窗口过程

只需要在第三步,和第四部多加一份即可

//第三部:创建窗口(返回之前发送WM_CREATE)

HWND hWndParent = CreateWindow("win", "纯API创建窗口", WS_OVERLAPPEDWINDOW, 50, 50, 500, 500, NULL, NULL, hInstance, NULL);

HWND hWndParent2 = CreateWindow("win", "纯API创建窗口", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hInstance, NULL);

//第四部:显示

ShowWindow(hWndParent, SW_SHOWNORMAL);

ShowWindow(hWndParent2, SW_SHOWNORMAL);

//更新窗口(发送WM_PAINT)

UpdateWindow(hWndParent);

UpdateWindow(hWndParent2);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态链接库是一种可重定位的二进制文件,它包含了一些可供其他程序调用的函数或数据。在 Windows 平台上,动态链接库采用 .dll 后缀名,而在 Linux 平台上则采用 .so 后缀名。在本文中,我们将介绍如何使用 MFC 调用 C 语言编写的动态链接库。 # 创建动态链接库 在 Windows 平台上,可以使用 Visual Studio 创建动态链接库。下面是一个简单的示例: ```c // mydll.h #ifndef MYDLL_H #define MYDLL_H #ifdef __cplusplus extern "C" { #endif __declspec(dllexport) int add(int a, int b); #ifdef __cplusplus } #endif #endif // MYDLL_H // mydll.c #include "mydll.h" int add(int a, int b) { return a + b; } ``` 这个动态链接库包含一个 add 函数,可以对两个整数求和。 # 调用动态链接库 在 MFC 项目中调用动态链接库,需要进行以下几个步骤: 1. 定义一个函数指针类型,指向动态链接库中的函数。 ```c++ typedef int (*AddFunc)(int, int); ``` 2. 加载动态链接库。 ```c++ HINSTANCE hinstLib = LoadLibrary(TEXT("mydll.dll")); if (hinstLib == NULL) { AfxMessageBox(TEXT("Failed to load library.")); return; } ``` 3. 获取动态链接库中的函数地址。 ```c++ AddFunc addFunc = (AddFunc)GetProcAddress(hinstLib, "add"); if (addFunc == NULL) { AfxMessageBox(TEXT("Failed to get function address.")); FreeLibrary(hinstLib); return; } ``` 4. 调用动态链接库中的函数。 ```c++ int result = addFunc(1, 2); CString str; str.Format(TEXT("1 + 2 = %d"), result); AfxMessageBox(str); ``` 5. 卸载动态链接库。 ```c++ FreeLibrary(hinstLib); ``` 完整的 MFC 代码示例: ```c++ typedef int (*AddFunc)(int, int); void CMyDlg::OnButton1() { HINSTANCE hinstLib = LoadLibrary(TEXT("mydll.dll")); if (hinstLib == NULL) { AfxMessageBox(TEXT("Failed to load library.")); return; } AddFunc addFunc = (AddFunc)GetProcAddress(hinstLib, "add"); if (addFunc == NULL) { AfxMessageBox(TEXT("Failed to get function address.")); FreeLibrary(hinstLib); return; } int result = addFunc(1, 2); CString str; str.Format(TEXT("1 + 2 = %d"), result); AfxMessageBox(str); FreeLibrary(hinstLib); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值