|
发表于 2022/8/27 15:27
|
显示全部楼层
|阅读模式
|Google Chrome 104.0.5112.102 |Windows 10
本帖最后由 Hileb 于 2022/10/3 17:45 编辑
制造窗口于信息!
首先,需要有一个窗口:下面是Dev-C++提供的一个示例:
- #include <windows.h>
- /* This is where all the input to the window goes to */
- LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
- switch(Message) {
-
- /* Upon destruction, tell the main thread to stop */
- case WM_DESTROY: {
- PostQuitMessage(0);
- break;
- }
-
- /* All other messages (a lot of them) are processed using default procedures */
- default:
- return DefWindowProc(hwnd, Message, wParam, lParam);
- }
- return 0;
- }
- /* The 'main' function of Win32 GUI programs: this is where execution starts */
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
- WNDCLASSEX wc; /* A properties struct of our window */
- HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
- MSG msg; /* A temporary location for all messages */
- /* zero out the struct and set the stuff we want to modify */
- memset(&wc,0,sizeof(wc));
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
- wc.hInstance = hInstance;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-
- /* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wc.lpszClassName = "WindowClass";
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
- wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
- if(!RegisterClassEx(&wc)) {
- MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
- return 0;
- }
- hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, /* x */
- CW_USEDEFAULT, /* y */
- 640, /* width */
- 480, /* height */
- NULL,NULL,hInstance,NULL);
- if(hwnd == NULL) {
- MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
- return 0;
- }
- /*
- This is the heart of our program where all input is processed and
- sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
- this loop will not produce unreasonably high CPU usage
- */
- while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
- TranslateMessage(&msg); /* Translate key codes to chars if present */
- DispatchMessage(&msg); /* Send it to WndProc */
- }
- return msg.wParam;
- }
复制代码
这段代码的意思非常容易看懂,int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)相当于main,但是如果有main,那么会发生什么呢?你可以自己试试。
它创建看一个窗口,设置它,显示它,然后进入了一个循环:
- /*
- This is the heart of our program where all input is processed and
- sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
- this loop will not produce unreasonably high CPU usage
- */
- while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
- TranslateMessage(&msg); /* Translate key codes to chars if present */
- DispatchMessage(&msg); /* Send it to WndProc */
- }
复制代码
显然,这个循环是程序的核心,如果把它删除,那么窗口在显示出来后程序便结束了。
在这个循环中,接受消息,翻译消息,发送消息。
在LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)中,我们可以进行一些事情,从Dev-C++所给出的示例可以看出,当WM_DESTROY时,会PostQuitMessage(0);。其他按默认方式处理。
我们可以加上一些东西:
这时,你会发现点击小叉叉没办法关闭窗口了,因为点击小叉叉时WM_CLOSE,因为WM_CLOSE时什么也不干,所以按小叉叉也不会有什么功能。
现在,加上一句:
- MessageBox(hwnd,"helloworld","helloworld",NULL);
复制代码
这时,按下叉叉会显示helloworld。
菜单与信息
你可以在WinMain中加上:
- wc.lpszMenuName = "MAINMENU";
复制代码
它可以使得你的窗口有一个菜单
你可以新建一个叫resource.rc的文件在你的工程里:
可以这么写:
- MAINMENU MENU
- {
- POPUP "&母"
- {
- MENUITEM "&子1", 1000
- MENUITEM "&子2", 1001
- MENUITEM SEPARATOR//横线
- MENUITEM "子3", 1002
- POPUP "&再嵌套"
- {
- MENUITEM "&子子", 1003
- }
- }
- MENUITEM "1004", 1004
- }
复制代码
然后再他们被按下时:会有WM_COMMAND,你可以这样处理:
- case WM_COMMAND:{
- switch(LOWORD(wParam)) {
- case 1002:{
- MessageBox(hwnd,"helloworld","1002",NULL);
- break;
- }
- case 1004:
- MessageBox(hwnd,"helloworld","1004",NULL);
- break;
- }
- break;
- }
复制代码
显然,在按下“子3”时,会显示1002,按下“1004”时,会显示1004.
然后,你就可以自由地发挥去做你的菜单了!
绘图与信息
你可以在LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)中,加入:
- PAINTSTRUCT ps;//画笔
- HDC hdc;//绘图句柄
复制代码
和
- case WM_PAINT:{
- //开始绘图
- hdc=BeginPaint(hwnd,&ps);
- //绘图
- //Windows_paint(hdc,hwnd);
- //结束绘图
- EndPaint(hwnd,&ps);
- break;
- }
复制代码
然后你就可以绘图了!
先绘制一行文字,有一个简单的方法:
- TextOut(hdc,0,0,"绘制一行文字!",12);
复制代码
当然,放在这里会显得特别地,不好看,所以,加一个:
- void Windows_paint(HDC hdc,HWND hwnd){
- //两次加载
- //获取客户端大小
- RECT rt;
- GetClientRect(hwnd,&rt);
- int WC_width=rt.right-rt.left;
- int WC_higth=rt.bottom-rt.top;
- //创建位图
- HBITMAP background=CreateCompatibleBitmap(hdc,WC_width,WC_higth);
- //创建兼容DC
- HDC ohdc=CreateCompatibleDC(hdc);
- SelectObject(ohdc,background);
- //绘制物品
- TextOut(hdc,0,0,"绘制一行文字!",12);
- //合并
- BitBlt(hdc,0,0,WC_width,WC_higth,ohdc,0,0,SRCCOPY);
- }
复制代码
你可以用InvalidateRect(hwnd,NULL,TRUE);去更新;
-----显示图片!-----
一个全局变量:
在WinMain中将它初始化:
加上:
- void Paint_background(HWND hwnd,HDC hdc,LPCSTR str){//绘制一张图片的实验
- //加载图片
- HBITMAP bitmap=(HBITMAP)(LoadImageA(this_windows,str,IMAGE_BITMAP,0,0,0x0010));
- HDC ohdc=CreateCompatibleDC(hdc);
- SelectObject(ohdc,bitmap);
- //贴图
- BitBlt(hdc,0,0,
- 640,//图片宽度
- 480,//图片高度
- ohdc,0,0,SRCCOPY);
- }
复制代码
然后在Windows_paint中加上:
- Paint_background(hwnd,ohdc,"1.bmp");
复制代码
//(一般都是后面挡住前面,例如Paint_background在TextOut后,则会将其挡住。)
然后就可以显示准备好的640x480的1.bmp(也可以把大小作为参数)
------绘制假按钮!--------
- class Button{
- public:
- bool isEmpty=true;
- int stx;//Æeê¼x
- int sty;//Æeê¼y
- int _x;//x
- int _y;//y
- LPCSTR path;//bmp·¾¶ Î′Ñ¡Ôñ
- // LPCWSTR road2;//òÑÑ¡Ôñ
- // LPCWSTR road3;//òÑ°′ÏÂ
- bool isDown=0;
- bool *show;
- //éèÖÃ
- set(int x,int y,int x_,int y_,LPCSTR str,bool *show_){
- stx=x;
- sty=y;
- _x=x_;
- _y=y_;
- path=str;
- isEmpty=false;
- show=show_;
- }
-
- };
- Button newButton(int x,int y,int x_,int y_,LPCSTR str,bool *show_){
- Button button;
- button.set(x, y, x_,y_,str,show_);
- return button;
- }
- void paint_button(HWND hwnd,HDC hdc,Button button){//»æÖÆò»ÕÅí¼Æ¬μÄêμÑé
- //¼óÔØí¼Æ¬
- if(*(button.show)==true){
- HBITMAP bitmap=(HBITMAP)(LoadImageA(this_windows,button.path,IMAGE_BITMAP,0,0,0x0010));
- //»æÖÆí¼Æ¬
- //′′½¨DC
- HDC ohdc=CreateCompatibleDC(hdc);
- SelectObject(ohdc,bitmap);
- //ìùí¼
- BitBlt(hdc,button.stx,button.sty,
- (button._x),//í¼Æ¬¿í′ø
- (button._y),//í¼Æ¬¸ß¶è
- ohdc,0,0,SRCCOPY);
- }
- }
- bool canshow=true;
- Button button1=newButton(10,10,10,10,"button.bmp",&canshow);
复制代码
在Windows_paint中加入:
- paint_button(hwnd,ohdc,button1);
复制代码
在case 1004:中加入:
- canshow=!canshow;
- InvalidateRect(hwnd,NULL,TRUE);
复制代码
当canshow为true时,按键会显示,而按1004会改变canshow且刷新!
------使按钮会被按到!--------
在class Button中加入:
- in(int x,int y){
- if(x>=stx && x<=(stx+_x) && y>=sty && y<=(sty+_y))return true;
- else false;
- }
复制代码
在WndProc加入:
- case WM_LBUTTONDOWN:{//点击鼠标左键时
- //获取点击坐标
- int cx=LOWORD(lParam);
- int cy=HIWORD(lParam);
- //
- if(*(button1.show)==true){
- if(button1.in(cx,cy)){
- canshow=!canshow;
- }
- }
-
- InvalidateRect(hwnd,NULL,TRUE);//更新
- break;
- }
复制代码
当鼠标点击,按钮显示,且按钮的区域被点击时,canshow发生改变,表现为按下按钮后按钮消失!
当然,你也可以修改class Button,让它有多个贴图和多个状态,例如:
WM_MOUSEMOVE//鼠标移动,鼠标指着按钮时按钮高亮。
按钮被点击颜色变深。。。以及一些别的。。。
也可以加一个class Buttons去批量管理Button,而不用手动去搞,
毕竟这样的东西是可以cv的
------------------------------------
正常人前端后端都要有的啦!
https://www.cnblogs.com/DOMLX/p/9601511.html
------------------------------------
你可以在winuser.h里找到WM_XXXXX,根据它的名字,你应该知道怎么用;
------------------------------------
一个小工程:github:solar stories v1.14.5.14 |
|