即将两年的.NET经验,一年的BMC经验,作为一个电子专业的人来说,心中仍然保留着对C和C++的情结。
最近项目空闲之余在看Windows Programming和Windows via C/C++,并且用C++为我们开发的类库制作安装程序,虽然只是简单的Windows C程序,但是那份成就感油然而生。本文记录开发这个小程序过程中的心得:
1、基于对话框的windows程序
虽然说标准的Windows程序总是由用户注册的窗口类开始的,并且程序员需要自己用while来接收应用程序消息队列里的消息,并处理。但是如果想要快速开发小程序的话,可以像下面这样基于对话框的来开始程序。对话框自动建立消息循环,接收消息,我们要做的只是定义一个对话框处理函数。
1 2 3 4 5 6 7 8 9 | int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE , PTSTR szCmdLine, int iCmdShow) { DialogBox(hInstance...,DlgProc); return 0; } |
2、检查内存泄漏
虽说是个小程序,但是在最后执行的时候,程序返回后,windows弹出应用程序出现错误。我猜想是内存泄漏了。实在惭愧,这么一个小程序都能搞出内存泄漏。后来在网上查到一个检查内存泄漏的方法:http://www.cppblog.com/Lyt/archive/2009/03/22/77517.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #define _CRTDBG_MAP_ALLOC #include <Windows.h> #include <tchar.h> #include <stdio.h> #include <stdlib.h> #include <crtdbg.h> int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE , PTSTR szCmdLine, int iCmdShow) { hInstance = hInstance; ... _CrtDumpMemoryLeaks(); return 0; } |
这里的_CrtDumpMemoryLeaks()会在vs的Output窗口中给出内存泄漏的报告。
3、根据对话框句柄无法获取对话框的资源ID
虽说GetWindowLong (hwndChild, GWL_ID) ;是通过句柄得到窗口资源ID,但是当句柄是对话框句柄是是无效的。另外相关函数如下:
1 2 3 | id = GetDlgCtrlID (hwndChild); hwndChild = GetDlgItem(hwndParent, id); |
4、GetWindowRect(hDlg,&rect);返回窗口的大小,返回的rect中的right和bottom竟然是窗口的width和height,真不知道为什么取名字要那么歧义。。GetSystemMetrics(SM_CXFULLSCREEN)和GetSystemMetrics(SM_CYFULLSCREEN)获得显示屏的像素信息。
MoveWindow(hDlg,inewLeft,inewTop,width,height,FALSE);可以设置窗口的位置。
5、设置checkbox:
1 2 3 | SendMessage(hwnd, BM_SETCHECK, BST_CHECKED, 0); SendMessage(hwnd, BM_SETCHECK, BST_UNCHECKED, 0); SendMessage(hwnd, BM_GETCHECK, 0, 0)); |
6、FindFirstFile的目标文件可以有通配符,但是必须是全路径。还可用来判断路径是否存在(FILE_ATTRIBUTE_DIRECTORY)
1 2 3 4 5 6 7 8 | WIN32_FIND_DATA FindFileData; HANDLE hFind = FindFirstFile(tmp,&FindFileData); if (INVALID_HANDLE_VALUE == hFind){ } else { FindClose(hFind); } |
7、字符串处理
_tcscpy、_tcscat、_tcslen、_tcscmp、_tcsstr
8、注册表操作,如果要设置环境变量,必须直接在注册表中设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | RegOpenKeyEx(HKEY_LOCAL_MACHINE ,TEXT( "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\" ) ,0 ,KEY_ALL_ACCESS ,&hEnvKEY) //读取键值的时候可以先读一次,获取需要的缓冲区长度和数据类型 RegQueryValueEx(hEnvKEY,TEXT( "Path" ),NULL,&dwType,NULL,&cbData) RegQueryValueEx(hEnvKEY,TEXT( "Path" ),NULL,&dwType,lpbOrignalEnvPath,&cbData); //返回的LPBYTE其实已经是字符数组了,直接强转就可以了 TCHAR * szOrignalEnvPath = ( TCHAR *)lpbOrignalEnvPath; #ifdef _UNICODE,UNICODE LSTATUS status = RegSetValueEx(hEnvKEY,TEXT( "Path" ),NULL,dwType,( LPBYTE )szTargetEnvPath,_tcslen(szTargetEnvPath)*2+2); #else LSTATUS status = RegSetValueEx(hEnvKEY,TEXT( "Path" ),NULL,dwType,( LPBYTE )szTargetEnvPath,_tcslen(szTargetEnvPath)+1); //设置完后可以通过下面方法,通知系统进程,环境变量变化了。这也提示我们在编写应用程序的时候有时需要处理WM_SETTINGCHANGE的意义 SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, ( LPARAM )TEXT( "Environment" )); |
9、获取系统变量和环境变量
1 2 3 4 | //同样可以通过调用两次来获取缓冲区长度 dwSize = GetEnvironmentVariable(TEXT( "HOMEDRIVE" ),NULL,0); szHomeDrive = new TCHAR [dwSize+1]; GetEnvironmentVariable(TEXT( "HOMEDRIVE" ),szHomeDrive,dwSize+1); |
10、C多文件编译、作用域和存储周期
http://www.cnblogs.com/P_Chou/archive/2012/05/25/2518097.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义