即將兩年的.NET經驗,一年的BMC經驗,作為一個電子專業的人來說,心中仍然保留著對C和C++的情結。
最近項目空閑之餘在看Windows Programming和Windows via C/C++,並且用C++為我們開發的類庫製作安裝程式,雖然只是簡單的Windows C程式,但是那份成就感油然而生。本文記錄開發這個小程式過程中的心得:
1、基於對話方塊的windows程式
雖然說標準的Windows程式總是由使用者註冊的視窗類別開始的,並且程式員需要自己用while來接收應用程式訊息佇列裡的訊息,並處理。但是如果想要快速開發小程式的話,可以像下面這樣基於對話方塊的來開始程式。對話方塊自動建立訊息迴圈,接收訊息,我們要做的只是定義一個對話方塊處理函數。
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
#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,但是當控制代碼是對話方塊控制代碼是是無效的。另外相關函數如下:
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:
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)
WIN32_FIND_DATA FindFileData;HANDLE hFind = FindFirstFile(tmp,&FindFileData);if(INVALID_HANDLE_VALUE == hFind){}else{FindClose(hFind);}
7、字串處理
_tcscpy、_tcscat、_tcslen、_tcscmp、_tcsstr
8、註冊表操作,如果要設定環境變數,必須直接在註冊表中設定
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,UNICODELSTATUS status = RegSetValueEx(hEnvKEY,TEXT("Path"),NULL,dwType,(LPBYTE)szTargetEnvPath,_tcslen(szTargetEnvPath)*2+2);#elseLSTATUS status = RegSetValueEx(hEnvKEY,TEXT("Path"),NULL,dwType,(LPBYTE)szTargetEnvPath,_tcslen(szTargetEnvPath)+1);//設定完後可以通過下面方法,通知系統進程,環境變數變化了。這也提示我們在編寫應用程式的時候有時需要處理WM_SETTINGCHANGE的意義SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)TEXT("Environment"));
9、擷取系統變數和環境變數
//同樣可以通過調用兩次來擷取緩衝區長度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