设为首页收藏本站

ZMX - IT技术交流论坛 - 无限Perfect,追求梦想 - itzmx.com

 找回密码
 注册论坛

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

用百度帐号登录

只需两步,快速登录

搜索
查看: 187|回复: 4

c艹,在Dev-c++中制造窗口!(更新中)

[复制链接]

签到天数: 295 天

[LV.8]以坛为家I

发表于 2022/8/27 15:27 | 显示全部楼层 |阅读模式 |Google Chrome 104.0.5112.102|Windows 10
天涯海角搜一下: 百度 谷歌 360 搜狗 有道 雅虎 必应 即刻
本帖最后由 Hileb 于 2022/10/3 17:45 编辑

制造窗口于信息
首先,需要有一个窗口:下面是Dev-C++提供的一个示例:
  1. #include <windows.h>

  2. /* This is where all the input to the window goes to */
  3. LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
  4.         switch(Message) {
  5.                
  6.                 /* Upon destruction, tell the main thread to stop */
  7.                 case WM_DESTROY: {
  8.                         PostQuitMessage(0);
  9.                         break;
  10.                 }
  11.                
  12.                 /* All other messages (a lot of them) are processed using default procedures */
  13.                 default:
  14.                         return DefWindowProc(hwnd, Message, wParam, lParam);
  15.         }
  16.         return 0;
  17. }

  18. /* The 'main' function of Win32 GUI programs: this is where execution starts */
  19. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  20.         WNDCLASSEX wc; /* A properties struct of our window */
  21.         HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
  22.         MSG msg; /* A temporary location for all messages */

  23.         /* zero out the struct and set the stuff we want to modify */
  24.         memset(&wc,0,sizeof(wc));
  25.         wc.cbSize                 = sizeof(WNDCLASSEX);
  26.         wc.lpfnWndProc         = WndProc; /* This is where we will send messages to */
  27.         wc.hInstance         = hInstance;
  28.         wc.hCursor                 = LoadCursor(NULL, IDC_ARROW);
  29.        
  30.         /* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
  31.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  32.         wc.lpszClassName = "WindowClass";
  33.         wc.hIcon                 = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
  34.         wc.hIconSm                 = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */

  35.         if(!RegisterClassEx(&wc)) {
  36.                 MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
  37.                 return 0;
  38.         }

  39.         hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
  40.                 CW_USEDEFAULT, /* x */
  41.                 CW_USEDEFAULT, /* y */
  42.                 640, /* width */
  43.                 480, /* height */
  44.                 NULL,NULL,hInstance,NULL);

  45.         if(hwnd == NULL) {
  46.                 MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
  47.                 return 0;
  48.         }

  49.         /*
  50.                 This is the heart of our program where all input is processed and
  51.                 sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
  52.                 this loop will not produce unreasonably high CPU usage
  53.         */
  54.         while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
  55.                 TranslateMessage(&msg); /* Translate key codes to chars if present */
  56.                 DispatchMessage(&msg); /* Send it to WndProc */
  57.         }
  58.         return msg.wParam;
  59. }
复制代码

这段代码的意思非常容易看懂,int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)相当于main,但是如果有main,那么会发生什么呢?你可以自己试试。
它创建看一个窗口,设置它,显示它,然后进入了一个循环:
  1. /*
  2.                 This is the heart of our program where all input is processed and
  3.                 sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
  4.                 this loop will not produce unreasonably high CPU usage
  5.         */
  6.         while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
  7.                 TranslateMessage(&msg); /* Translate key codes to chars if present */
  8.                 DispatchMessage(&msg); /* Send it to WndProc */
  9.         }
复制代码

显然,这个循环是程序的核心,如果把它删除,那么窗口在显示出来后程序便结束了。
在这个循环中,接受消息,翻译消息,发送消息。

在LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)中,我们可以进行一些事情,从Dev-C++所给出的示例可以看出,当WM_DESTROY时,会PostQuitMessage(0);。其他按默认方式处理。
我们可以加上一些东西:
  1. case WM_CLOSE:{
  2.                        
  3.                         break;
  4.                 }
复制代码

这时,你会发现点击小叉叉没办法关闭窗口了,因为点击小叉叉时WM_CLOSE,因为WM_CLOSE时什么也不干,所以按小叉叉也不会有什么功能。
现在,加上一句:
  1. MessageBox(hwnd,"helloworld","helloworld",NULL);
复制代码

这时,按下叉叉会显示helloworld。
菜单与信息
你可以在WinMain中加上:
  1. wc.lpszMenuName  = "MAINMENU";
复制代码

它可以使得你的窗口有一个菜单
你可以新建一个叫resource.rc的文件在你的工程里:
可以这么写:

  1. MAINMENU MENU
  2. {
  3. POPUP "&母"
  4. {
  5.   MENUITEM "&子1", 1000
  6.   MENUITEM "&子2", 1001
  7.   MENUITEM SEPARATOR//横线
  8.   MENUITEM "子3", 1002
  9.   POPUP "&再嵌套"
  10. {
  11.   MENUITEM "&子子", 1003
  12. }
  13. }
  14.   MENUITEM "1004", 1004
  15. }
复制代码

然后再他们被按下时:会有WM_COMMAND,你可以这样处理:
  1. case WM_COMMAND:{
  2.                         switch(LOWORD(wParam)) {
  3.                                 case 1002:{
  4.                                         MessageBox(hwnd,"helloworld","1002",NULL);
  5.                                         break;
  6.                                 }
  7.                                 case 1004:
  8.                                         MessageBox(hwnd,"helloworld","1004",NULL);
  9.                                         break;
  10.                         }
  11.                         break;
  12.                 }
复制代码

显然,在按下“子3”时,会显示1002,按下“1004”时,会显示1004.
然后,你就可以自由地发挥去做你的菜单了!
绘图与信息
你可以在LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)中,加入:
  1. PAINTSTRUCT ps;//画笔
  2.         HDC hdc;//绘图句柄
复制代码


  1. case WM_PAINT:{
  2.                         //开始绘图
  3.                         hdc=BeginPaint(hwnd,&ps);
  4.                         //绘图
  5.                         //Windows_paint(hdc,hwnd);
  6.                         //结束绘图
  7.                         EndPaint(hwnd,&ps);
  8.                         break;
  9.                 }
复制代码

然后你就可以绘图了!
先绘制一行文字,有一个简单的方法:
  1. TextOut(hdc,0,0,"绘制一行文字!",12);
复制代码

当然,放在这里会显得特别地,不好看,所以,加一个:
  1. void Windows_paint(HDC hdc,HWND hwnd){
  2.         //两次加载
  3.         //获取客户端大小
  4.         RECT rt;
  5.         GetClientRect(hwnd,&rt);
  6.         int WC_width=rt.right-rt.left;
  7.         int WC_higth=rt.bottom-rt.top;
  8.         //创建位图
  9.         HBITMAP background=CreateCompatibleBitmap(hdc,WC_width,WC_higth);
  10.         //创建兼容DC
  11.         HDC ohdc=CreateCompatibleDC(hdc);
  12.         SelectObject(ohdc,background);
  13.         //绘制物品
  14.         TextOut(hdc,0,0,"绘制一行文字!",12);
  15.         //合并
  16.         BitBlt(hdc,0,0,WC_width,WC_higth,ohdc,0,0,SRCCOPY);
  17. }
复制代码

你可以用InvalidateRect(hwnd,NULL,TRUE);去更新;
-----显示图片!-----
一个全局变量:
  1. HINSTANCE this_windows;
复制代码

在WinMain中将它初始化:
  1. this_windows= hInstance;
复制代码

加上:
  1. void  Paint_background(HWND hwnd,HDC hdc,LPCSTR str){//绘制一张图片的实验
  2.         //加载图片
  3.         HBITMAP bitmap=(HBITMAP)(LoadImageA(this_windows,str,IMAGE_BITMAP,0,0,0x0010));
  4.         HDC ohdc=CreateCompatibleDC(hdc);
  5.         SelectObject(ohdc,bitmap);
  6.         //贴图
  7.         BitBlt(hdc,0,0,
  8.         640,//图片宽度
  9.         480,//图片高度
  10.         ohdc,0,0,SRCCOPY);
  11. }
复制代码

然后在Windows_paint中加上:
  1. Paint_background(hwnd,ohdc,"1.bmp");
复制代码

//(一般都是后面挡住前面,例如Paint_background在TextOut后,则会将其挡住。)
然后就可以显示准备好的640x480的1.bmp(也可以把大小作为参数)
------绘制假按钮!--------
  1. class Button{
  2.         public:
  3.                 bool isEmpty=true;
  4.                 int stx;//&#198;eê&#188;x
  5.                 int sty;//&#198;eê&#188;y
  6.                 int _x;//x
  7.                 int _y;//y
  8.                 LPCSTR path;//bmp&#194;·&#190;&#182; &#206;′&#209;&#161;&#212;&#241;
  9. //                LPCWSTR road2;//ò&#209;&#209;&#161;&#212;&#241;
  10. //                LPCWSTR road3;//ò&#209;°′&#207;&#194;
  11.                 bool isDown=0;
  12.                 bool *show;
  13.                 //éè&#214;&#195;
  14.                 set(int x,int y,int x_,int y_,LPCSTR str,bool *show_){
  15.                         stx=x;
  16.                         sty=y;
  17.                         _x=x_;
  18.                         _y=y_;
  19.                         path=str;
  20.                         isEmpty=false;
  21.                         show=show_;
  22.                 }
  23.        
  24. };
  25. Button newButton(int x,int y,int x_,int y_,LPCSTR str,bool *show_){
  26.         Button button;
  27.         button.set(x, y, x_,y_,str,show_);
  28.         return button;
  29. }
  30. void  paint_button(HWND hwnd,HDC hdc,Button button){//&#187;&#230;&#214;&#198;ò&#187;&#213;&#197;í&#188;&#198;&#172;μ&#196;êμ&#209;é
  31.         //&#188;ó&#212;&#216;í&#188;&#198;&#172;
  32.         if(*(button.show)==true){
  33.                 HBITMAP bitmap=(HBITMAP)(LoadImageA(this_windows,button.path,IMAGE_BITMAP,0,0,0x0010));
  34.         //&#187;&#230;&#214;&#198;í&#188;&#198;&#172;
  35.         //′′&#189;¨DC
  36.         HDC ohdc=CreateCompatibleDC(hdc);
  37.         SelectObject(ohdc,bitmap);
  38.         //ìùí&#188;
  39.         BitBlt(hdc,button.stx,button.sty,
  40.         (button._x),//í&#188;&#198;&#172;&#191;í′&#248;
  41.         (button._y),//í&#188;&#198;&#172;&#184;&#223;&#182;è
  42.         ohdc,0,0,SRCCOPY);
  43.         }
  44. }
  45. bool canshow=true;
  46. Button button1=newButton(10,10,10,10,"button.bmp",&canshow);
复制代码

在Windows_paint中加入:
  1. paint_button(hwnd,ohdc,button1);
复制代码

在case 1004:中加入:
  1. canshow=!canshow;
  2. InvalidateRect(hwnd,NULL,TRUE);
复制代码

当canshow为true时,按键会显示,而按1004会改变canshow且刷新!
------使按钮会被按到!--------
在class  Button中加入:
  1. in(int x,int y){
  2.                         if(x>=stx && x<=(stx+_x) && y>=sty && y<=(sty+_y))return true;
  3.                         else false;
  4.                 }
复制代码

在WndProc加入:
  1. case WM_LBUTTONDOWN:{//点击鼠标左键时
  2.                         //获取点击坐标
  3.                         int cx=LOWORD(lParam);
  4.                         int cy=HIWORD(lParam);
  5.                         //
  6.                         if(*(button1.show)==true){
  7.                                 if(button1.in(cx,cy)){
  8.                                         canshow=!canshow;
  9.                                 }
  10.                         }
  11.                        
  12.                         InvalidateRect(hwnd,NULL,TRUE);//更新
  13.                         break;
  14.                 }
复制代码

当鼠标点击,按钮显示,且按钮的区域被点击时,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
欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复

使用道具 举报

签到天数: 3989 天

[LV.Master]伴坛终老

发表于 2022/8/27 18:48 | 显示全部楼层 |Google Chrome 104.0.5112.102|Windows 10
这可能就是大佬吧。。写了这么多忙猜花了一小时!
欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复 支持 1 反对 0

使用道具 举报

签到天数: 295 天

[LV.8]以坛为家I

 楼主| 发表于 2022/8/27 19:03 | 显示全部楼层 |Google Chrome 73.0.3683.121|Windows 7
本帖最后由 Hileb 于 2022/8/28 09:22 编辑
小樱 发表于 2022/8/27 18:48
这可能就是大佬吧。。写了这么多忙猜花了一小时!


不,这个是根本不看windows给了什么api就瞎做的小白
欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复 支持 反对

使用道具 举报

签到天数: 3989 天

[LV.Master]伴坛终老

发表于 2022/8/28 00:34 | 显示全部楼层 |Google Chrome 104.0.5112.102|Windows 10
https://developer.mozilla.org/zh-CN/docs/WebAssembly/Concepts
浏览器里好像可以运行rust/C/C艹
[发帖际遇]: 小樱 乐于助人,奖励 6 贡献. 幸运榜 / 衰神榜
欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复 支持 反对

使用道具 举报

签到天数: 295 天

[LV.8]以坛为家I

 楼主| 发表于 2022/8/28 10:22 | 显示全部楼层 |Google Chrome 104.0.5112.102|Windows 10
小樱 发表于 2022/8/28 00:34
https://developer.mozilla.org/zh-CN/docs/WebAssembly/Concepts
浏览器里好像可以运行rust/C/C艹

好高级!
欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册论坛 新浪微博账号登陆用百度帐号登录

本版积分规则

手机版|Archiver|Mail me|网站地图|IT技术交流论坛 ( 闽ICP备13013206号-7 )

GMT+8, 2022/12/5 21:58 , Processed in 0.356910 second(s), 20 queries , MemCache On.

Powered by itzmx! X3.4

© 2011- sakura

快速回复 返回顶部 返回列表