user-0 提问: 学了半天的C语言了，如果只是”画简单的轮子“，应该学什么

回复:
user: user-1
content: 脚本也能很大程序自动化，帮助你的干活，py 很适合

user: user-2
content: 同样推荐 GUI程序设计原理（载请注明出自https://blog.csdn.net/qq_29344757/article/details/77817321） GUI(Graphical User Interface)即图形用户接口，是指用图形方式显示计算机操作的用户界面。相比于早期的计算机使用的命令行，图形界面对于用户来讲更易于接受。  1. 命令行应用程序    命令行应用程序是一种基于顺序执行结构的可执行程序，如Linux操作系统上的ls、gcc、ifconfig命令。这种可执行程序在执行过程中并不需要与用户交互，程序执行到最后后用户运行结果，如产生一个可执行程序或者给出错误信息。程序的运行有固定的开始和固定的结束。  2. 图形界面应用程序    随着计算机技术的发展，计算机日趋平民化，计算机用户不再是专业的计算机工作者。为非计算机专业的用户操作计算机，就产生了图形界面应用程序。GUI程序是一种基于消息驱动模型的可执行程序，程序的执行依赖于和用户的交互，实时响应用户操作。GUI程序执行后不会主动退出。    GUI应用程序都是基于窗口的，其程序流程伪代码如下：  void mian(int argc, char** argv) {     //1. 定义主窗口      //2. 创建主窗口      //3. 创建主窗口内的元素      //4. 显示主窗口      //5. 进入消息接收/处理循环     } 1 2 3 4 5 6 7 8 9 10 11 12   这段伪代码揭示了GUI应用程序的原理。不论是基于跨平台的Qt GUI应用程序，还是基于Windows的MFC等其他GUI应用程序，原理都是如此。    GUI程序执行后不会主动退出，都停留在接收消息，根据消息执行相应操作的循环。消息处理模型如下：  这里写图片描述    以触摸屏为例，当用户点击触摸屏，首先感知到屏幕上被触摸的XY坐标是操作系统内核空间的触摸屏设备驱动程序，然后设备驱动程序会将用户操作封装成消息传递给GUI程序运行时创建的消息队列，GUI程序在运行过程中需要实时处理队列中的消息，当队列没有消息时，程序将处于停滞状态。  3. windows平台上GUI程序示例    在Windows上实现GUI有很多方法，每一种方法都有着自己的一套开发理念和工具，常见的有：    a. Windows API：直接调用Windows底层绘图函数。涉及到底层的基本用c语言写的，这些API也是如此。    b. MFC：使用Windows API封装成控件类    c. Windows Form：基于.net的GUI开发，完全组件化但是需要.Net运行库支持  …    其中基于Windows API开发的GUI程序，即是函数调用 + Windows消息处理的方法，这是所有GUI程序的原理。    Windows API写GUI最基本的函数有：    a. 向系统注册GUI窗口RegisterClass(定义GUI窗口样式)    原型：  #define RegisterClass  RegisterClassW ATOM WINAPI RegisterClassW(__in CONST WNDCLASSW *lpWndClass); 1 2   b. 创建窗口或窗口元素CreateWindow()  #define CreateWindow  CreateWindowW #define CreateWindowW(lpClassName, lpWindowName, dwStyle, x, y,\ nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)     CreateWindowExW(0L,\ lpClassName, lpWindowName, dwStyle, x, y,\ nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam) 1 2 3 4 5   用户调用CreateWindow()函数，实则调用  CreateWindowW(     __in_opt LPCWSTR lpClassName,   //创建窗口     __in_opt LPCWSTR lpWindowName,  //窗口的标题     __in DWORD dwStyle,             //窗口的显示风格     __in int X,                     //窗口左上角x坐标     __in int Y,                     //窗口左上角y坐标     __in int nWidth,                //窗口的宽度     __in int nHeight,               //窗口的高度     __in_opt HWND hWndParent,       //父窗口的句柄     __in_opt HMENU hMenu,           //窗口菜单栏/子窗口的标识符     __in_opt HINSTANCE hInstance,   //应用程序实例的句柄     __in_opt LPVOID lpParam         //窗口的创建数据 ); 1 2 3 4 5 6 7 8 9 10 11 12 13   CreateWindowW调用的是CreateWindowExW()函数，CreateWindowExW()将CreateWindowW()的首参数置为0：  HWND WINAPI CreateWindowExW(     __in DWORD dwExStyle,                __in_opt LPCWSTR lpClassName,        __in_opt LPCWSTR lpWindowName,       __in DWORD dwStyle,                  __in int X,     __in int Y,     __in int nWidth,     __in int nHeight,     __in_opt HWND hWndParent,     __in_opt HMENU hMenu,     __in_opt HINSTANCE hInstance,     __in_opt LPVOID lpParam); 1 2 3 4 5 6 7 8 9 10 11 12 13   c. 显示创建好的窗口ShowWindow()  BOOL WINAPI ShowWindow(__in HWND hWnd, __in int nCmdShow);   1   hWnd指窗口句柄，nCmdShow指定窗口如何显示    d. 刷新屏幕上的窗口UpdateWindow()  WINUSERAPI BOOL WINAPI UpdateWindow(__in HWND hWnd); 1 2   e. 获取程序中消息队列中的消息GetMessage()  #define GetMessage  GetMessageW BOOL WINAPI GetMessageW(__out LPMSG lpMsg, __in_opt HWND hWnd, __in UINT wMsgFilterMin, __in UINT wMsgFilterMax); 1 2   f. 翻译系统消息TranslateMessage()  WINUSERAPI BOOL WINAPI TranslateMessage(__in CONST MSG *lpMsg); 1   内核空间发到用户空间的消息需要调用此函数翻译后才能传给GUI程序对应的消息处理函数    g. 将消息发给窗口处理函数DispatchMessage()  #define DispatchMessage  DispatchMessageW WINUSERAPI LRESULT WINAPI DispatchMessageW(__in CONST MSG *lpMsg); 1 2   新建visual studio 2010的Win32工程：  #define STYLE_NAME    L"WIN" #define BUTTON_ID     7777  //窗口消息处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     /* 调用系统提供的默认消息处理函数 */     return DefWindowProc(hWnd, message, wParam, lParam); }  /* 相当于c/c++的main函数 */ BOOL WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {     MSG msg = {};           //定义一个消息队列     HWND main_hwnd = NULL;  //窗口句柄     HWND hwnd = NULL;       //窗口内的元素句柄     WNDCLASS WndClass = {0};//定义描述窗口样式         //为窗口样式赋值     WndClass.style         = 0;     WndClass.cbClsExtra    = 0;     WndClass.cbClsExtra    = 0;     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW);          // 定义窗口背景色     WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);     // 定义鼠标样式     WndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // 定义窗口左上角图标     WndClass.hInstance     = hInstance;                       // 定义窗口式样属于当前应用程序     WndClass.lpfnWndProc   = WndProc;                         // 窗口消息处理函数     WndClass.lpszClassName = STYLE_NAME;                      // 窗口样式名     WndClass.lpszMenuName  = NULL;      //1. 将定义好的窗口式样注册到系统     RegisterClass(&WndClass);      //2. 创建窗口，返回窗口的句柄     main_hwnd = CreateWindow(STYLE_NAME,       // 通过定义好的窗口式样创建主窗口                         STYLE_NAME,            // 主窗口标题                         WS_OVERLAPPEDWINDOW,   // 创建后主窗口的显示风格                         CW_USEDEFAULT,         // 主窗口左上角 x 坐标                         CW_USEDEFAULT,         // 主窗口左上角 y 坐标                         CW_USEDEFAULT,         // 主窗口宽度                         CW_USEDEFAULT,         // 主窗口高度                         NULL,                  // 父窗口                         NULL,                  // 窗口菜单栏                         hInstance,             // 主窗口属于当前应用程序                         NULL);                 // 窗口参数      //获取该窗口的信息     hInstance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);      //3. 创建窗口内元素，即按钮     hwnd = CreateWindow(L"button",                               // 通过系统预定义式样创建窗口元素                         L"My Button",                            // 窗口元素标题                         WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,   // 窗口元素的显示风格                         50,                                      // 窗口元素在窗口中的左上角 x 坐标                         50,                                      // 窗口元素在窗口中的左上角 y 坐标                         200,                                     // 窗口元素的宽度                         60,                                      // 窗口元素的高度                         main_hwnd,                               // 窗口元素所在的父窗口                         (HMENU)BUTTON_ID,                        // 窗口元素 ID 值                         hInstance,                               // 窗口元素属于当前应用程序                         NULL);                                   // 窗口元素参数      ShowWindow(main_hwnd,nCmdShow); // 显示窗口     UpdateWindow(main_hwnd);        // 刷新窗口      //4. 循环接收系统消息     while (GetMessage(&msg, NULL, NULL, NULL) )     {         //翻译消息         TranslateMessage(&msg);          //将消息发给对应GUI的消息处理函数         DispatchMessage(&msg);      }      return TRUE; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78   编译运行：  这里写图片描述    程序运行窗口如图。对该窗口可以利用鼠标操作进行最大/小化，拖动等。用户利用鼠标操作该窗口时，操作系统的内核会收到用户的输入信息并转换为消息发给当前的GUI程序，GUI程序的WndProc()函数收到消息后，执行相应处理。在WndProc()中，调用DefWindowProc()执行默认处理，这就是为什么程序对鼠标的最大/小化操作、拖动等能响应，而在代码中我们并没有位这些操作设置响应函数的原因。    但是注意，点击关闭按钮后，窗口虽然被关闭了但是GUI程序并没有退出，显然这是因为DefWindowProc()对窗口关闭按钮并没有默认操作。在实际软件中有点击窗口关闭按钮并不一定是退出GUI程序，如windows的金山词霸，点击关闭按钮只是将其放到后台执行。另外，当鼠标点击“my button”按钮时并无反应，这也是因为消息处理函数并没有对应按钮消息的执行操作，修改如下：  HWND main_hwnd = NULL;  //窗口句柄  //窗口消息处理函数 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     //处理窗口关闭按钮     if (message == WM_DESTROY)         PostQuitMessage(0);      //处理窗口内按钮点击操作     if (message == WM_COMMAND)  //按钮按下操作属于WM_COMMAND     {         if (HIWORD(WM_COMMAND) == BN_CLICKED) //HIWORD(WM_COMMAND)表示从WM_COMMAND中拿到按钮是点击                                               //拖动还是长按，BN_CLICKED表示点击         {             //弹出对话框             MessageBox(main_hwnd, L"Hello Button!", L"Message", 0);         }     }      /* 其他操作调用系统提供的默认消息处理函数 */     return DefWindowProc(hWnd, message, wParam, lParam); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23   这样就能使得GUI程序能处理关闭按钮消息和按钮点击消息了。    综上，GUI程序的开发，分为两部分：    (1) 在代码中用程序创建窗口及窗口内元素    (2) 在消息处理函数中根据内核空间发来的消息做出对应的响应

user: user-3
content: 不打算当程序员就不应该学c++, 很多工具类的语言更合适, 比如说python

user: user-4
content: 引用 2 楼 yedaidai74 的回复:其实，我觉得这种画轮子，主要是让你熟悉c++编程的逻辑思维方式，为你今后解决更复杂的问题提供思维定式。所以还是得扎扎实实学好画轮子！ 楼上正解

user: user-5
content: 引用 3 楼 zhao4zhong1 的回复:越想走捷径的人，可能越晚到达目的地。 没想到赵四老师还是哲学家

user: user-6
content: 引用 8 楼 zhao3132453 的回复:破解，能看懂汇编就行 汇编？ 比c难上几百倍

user: user-7
content: 引用 11 楼 u014008391 的回复:学了C的入门了。拖控件从哪入手学， 老师有推荐的书吗  Qt或C++ Builder。  Qt的： 《大学计算机基础教育规划教材 Qt图形界面编程入门》 作  者 : 仇国巍 编著 出版日期 : 2017.03       页  数 : 276  图形用户界面（GUI）编程可以学习C++ Builder，架构先进（和C#一样拖控件），入门比较容易。  　　C++ Builder是真正的可视化的开发工具。C++ Builder可以用鼠标拖拉控件加上设置属性轻松的“设计”出一个程序的图形用户界面，利用可视的组件/控件像“搭积木”一样，以“所见即所得”的方式搭建应用程序的界面，这也是C++ Builder这个名字中Builder的概念。这样，只需要用C++语言编写业务逻辑代码，类似于DOS下文本界面编程，只要专注于实现业务逻辑功能就可以了，代码非常简洁。数据的输入和表现，都在图形用户界面，非常直观、易用。这就是RAD开发（Rapid Application Development，快速应用程序开发）。  书籍推荐： 《C++Builder 6程序设计教程（第二版）》 （陆卫忠，刘文亮　等编著 /2011-04-01 /科学出版社）（当当网） 《C++Builder 6编程实例精解》（赵明现），PDF，是数字版的，非扫描版的，里面还有一个俄罗斯方块游戏的完整实现。 《精彩C++Builder 6程序设计》（台湾 吴逸贤），里面有10几个简单小游戏的实现，可以自己看懂以后再重写，才是自己掌握的。 《C++ Builder 5高级编程实例精解》（刘滨 编著）都是较大的实用的程序。

user: user-0
content: 引用 9 楼 u010165006 的回复:[quote=引用 7 楼 u014008391 的回复:] [quote=引用 4 楼 u010165006 的回复:] 楼主想“组装”车，不是想“造”车，那就学组装技术好了。 请问组装技术怎么学呢，一头雾水[/quote]  首先组装技术也是技术，也要技术。比如拖控件，就是一种组装，用别人造好的控件。组装需要别人先造好，你在较高的层次组装，比如做一个媒体/CD播放器，组装不超过10行代码。[/quote]  学了C的入门了。拖控件从哪入手学， 老师有推荐的书吗

user: user-0
content: 引用 12 楼 u010165006 的回复:[quote=引用 11 楼 u014008391 的回复:] 学了C的入门了。拖控件从哪入手学， 老师有推荐的书吗  Qt或C++ Builder。  Qt的： 《大学计算机基础教育规划教材 Qt图形界面编程入门》 作  者 : 仇国巍 编著 出版日期 : 2017.03       页  数 : 276  图形用户界面（GUI）编程可以学习C++ Builder，架构先进（和C#一样拖控件），入门比较容易。  　　C++ Builder是真正的可视化的开发工具。C++ Builder可以用鼠标拖拉控件加上设置属性轻松的“设计”出一个程序的图形用户界面，利用可视的组件/控件像“搭积木”一样，以“所见即所得”的方式搭建应用程序的界面，这也是C++ Builder这个名字中Builder的概念。这样，只需要用C++语言编写业务逻辑代码，类似于DOS下文本界面编程，只要专注于实现业务逻辑功能就可以了，代码非常简洁。数据的输入和表现，都在图形用户界面，非常直观、易用。这就是RAD开发（Rapid Application Development，快速应用程序开发）。  书籍推荐： 《C++Builder 6程序设计教程（第二版）》 （陆卫忠，刘文亮　等编著 /2011-04-01 /科学出版社）（当当网） 《C++Builder 6编程实例精解》（赵明现），PDF，是数字版的，非扫描版的，里面还有一个俄罗斯方块游戏的完整实现。 《精彩C++Builder 6程序设计》（台湾 吴逸贤），里面有10几个简单小游戏的实现，可以自己看懂以后再重写，才是自己掌握的。 《C++ Builder 5高级编程实例精解》（刘滨 编著）都是较大的实用的程序。[/quote] 谢谢老师

user: user-8
content: 破解，能看懂汇编就行

user: user-0
content: 引用 4 楼 u010165006 的回复:楼主想“组装”车，不是想“造”车，那就学组装技术好了。 请问组装技术怎么学呢，一头雾水

user: user-7
content: 引用 7 楼 u014008391 的回复:[quote=引用 4 楼 u010165006 的回复:] 楼主想“组装”车，不是想“造”车，那就学组装技术好了。 请问组装技术怎么学呢，一头雾水[/quote]  首先组装技术也是技术，也要技术。比如拖控件，就是一种组装，用别人造好的控件。组装需要别人先造好，你在较高的层次组装，比如做一个媒体/CD播放器，组装不超过10行代码。

user: user-9
content: 越想走捷径的人，可能越晚到达目的地。

user: user-10
content: 其实，我觉得这种画轮子，主要是让你熟悉c++编程的逻辑思维方式，为你今后解决更复杂的问题提供思维定式。所以还是得扎扎实实学好画轮子！

user: user-11
content: 1.python就可以做到，厉害一点c也能写 2.MFC、QT等等等等都可以实现，非常多，同时你会发现用C开发完全不够，这里说的两个要用C++。 3.python，甚至可以用按键精灵。  解决的办法有很多，不同的人不同的视角，像我的视角就很窄，就看到这么一些路子。我在学C的时候也是很多的疑问，编个程序就能让机器人动起来？编个程序就能出来一个漂亮的软件？凭当时的小脑袋怎么想都想不通。建议你把C基础打扎实，再去请教你的老师，讨论你今后的发展方向，再专门学习。

user: user-9
content: 按键精灵 或 autohotkey

user: user-12
content: 表示以前也想过不怎么出力学习就想搞定这么复杂的功能，在门外汉看来这个功能很简单，然而实现起来是需要专业程序员才能搞定的，也就专业程序员才有资格说很简单

user: user-7
content: 楼主想“组装”车，不是想“造”车，那就学组装技术好了。