利用 RAMMap 來清記憶體的資料。
Download Path:
https://technet.microsoft.com/en-us/sysinternals/rammap.aspx
2016年4月15日 星期五
2016年3月14日 星期一
SetEnvironmentVariable VS getenv
最近發現一個奇怪的現象,
就是在 VS 的 cpp 裡呼叫 SetEnvironmentVariable 設定環境變數,
但從 Python code 裡印出 os.osenviron 卻看不到所設定的變數,
一查才發現,Python 裡的 os.osenviron 是用 getenv實作的。
GetEnvironmentVariable/SetEnvironmentVariable 是 Windows API,
而 setenv/getenv 是 CRT 函式。CRT 在開始的時候便會透過 Windows API GetEnvironmentStrings 將回傳值存入自己的資料結構之下(EX: MSVCR80!environ),
而此後 getenv 便是對這份副本做操作。
結論就是不要混用 SetEnvironmentVariable 和 getenv 啊!!
Ref:
就是在 VS 的 cpp 裡呼叫 SetEnvironmentVariable 設定環境變數,
但從 Python code 裡印出 os.osenviron 卻看不到所設定的變數,
一查才發現,Python 裡的 os.osenviron 是用 getenv實作的。
GetEnvironmentVariable/SetEnvironmentVariable 是 Windows API,
而 setenv/getenv 是 CRT 函式。CRT 在開始的時候便會透過 Windows API GetEnvironmentStrings 將回傳值存入自己的資料結構之下(EX: MSVCR80!environ),
而此後 getenv 便是對這份副本做操作。
結論就是不要混用 SetEnvironmentVariable 和 getenv 啊!!
Ref:
2015年8月18日 星期二
Writing DPI-Aware Desktop and Win32 Applications
在 Windows 上,依據 DPI 的設定可將應用程式分為三類:
Not DPI-aware Applications
沒有設定 DPI-aware 的應用程式,皆以 96 DPI 做 rendering。
系統的 Desktop Window Manager (DWM) 會自動縮放 (virtualizes and scales) 這些應用程式。
System-DPI Aware Application
從 Windows Vista 開始到 Windows 8,應用程式可以依據系統 DPI 的設定,自己去做最佳化,而不是透過 DWM 來做。但如果是在不同 DPI 的螢幕間移動,DWM 還是會自動縮放。
Per Monitor-DPI Aware Applications
從 Windows 8.1 開始,多了這個類別。當使用者改變了 DPI 設定或在不同 DPI 的螢幕間移動時,這些應用程式將會動態縮放。DWM 同樣不會去自動縮放這些應用程式。
DPI Virtualization and Scaling
從 Window Vista 開始,引進了新功能 DPI virtualization,這項功能會將沒有設定 DPI-aware 的應用程式,自動縮放其文字和其他 UI 元件。這樣應用程式的字在 high DPI 的螢幕上就不會看起來特別的小。而從 Window 8.1 開始,延展了 DPI virtualization 的功能,DPI 從系統層級變成螢幕層級。
Supporting Dynamic DPI Changes
那應用程式該做哪些事情來支援 DPI 的動態設定呢?
Ref : Writing DPI-Aware Desktop and Win32 Applications
- Set the DPI Awareness Level
可以透過 manifest 檔或 SetProcessDpiAwareness API 來做設定。 - Get the DPI for the current monitor
呼叫 GetDPIForMonitor API 來取得值。 - Listen for DPI changes
聆聽 WM_DPICHANGED 這個 windows message。 - Respond to DPI changes
收到上述訊息後,改變視窗大小或縮放 UI 元件等等。
Ref : Writing DPI-Aware Desktop and Win32 Applications
2013年10月18日 星期五
Windows Messsage: Clicking mouse button will also trigger mouse down event.
用 Microsoft Spy++ 攔了一下滑鼠相關的 messages,
發現原來只按滑鼠左鍵一樣也會觸發 WM_MOUSEMOVE 。
WM_SETCURSOR
WM_SETCURSOR
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_SETCURSOR
WM_SETCURSOR
WM_MOUSEMOVE
發現原來只按滑鼠左鍵一樣也會觸發 WM_MOUSEMOVE 。
WM_SETCURSOR
WM_SETCURSOR
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_SETCURSOR
WM_SETCURSOR
WM_MOUSEMOVE
2013年10月3日 星期四
Symbols and Symbol Files
當程式做完連結 (link) 後,連結器 (Linker) 除了產生 .exe 和 .dll 檔之外,也會額外產生
symbol 檔。symbol 檔包含了執行程式時所不需要的資料,但在除錯上就極為有用:
這些每一個項目都稱為 symbol,所以一個 symbol 檔會包含有很多 symbols,
symbol 檔的副檔名為 .pdb 或 .dbg,Visual C++ 6.0 Linker 之後只會產生 .pdb。
Ref: http://msdn.microsoft.com/en-us/library/windows/hardware/ff558825(v=vs.85).aspx
symbol 檔。symbol 檔包含了執行程式時所不需要的資料,但在除錯上就極為有用:
- 全域變數
- 區域變數
- 函式的名稱還有進入點的位址
- Frame pointer omission (FPO) 的紀錄
- 原始碼的行號
這些每一個項目都稱為 symbol,所以一個 symbol 檔會包含有很多 symbols,
symbol 檔的副檔名為 .pdb 或 .dbg,Visual C++ 6.0 Linker 之後只會產生 .pdb。
Ref: http://msdn.microsoft.com/en-us/library/windows/hardware/ff558825(v=vs.85).aspx
2013年9月30日 星期一
Symbol path for Windows debuggers
一般指定本地端的 symbol 檔路徑的指令如下,
如果電腦有連接網路最有效率的方法就是直接連 Symbol Server,
srv*symbolstore
Microsoft's symbol store:
.sympath srv*http://msdl.microsoft.com/download/symbols
建議加上 Cahce:
.sympath cache*;srv*http://msdl.microsoft.com/download/symbols
cache* 是指把 symbol 檔存到 default 的本地端,下次就不用載一次。
.sympath c:\MySymbols
而 Debugger 查詢 symbol 檔的順序為:- c:\MySymbols\symbols\dll
- c:\MySymbols\dll
- c:\MySymbols
- Current Directory
- Current Directory\dll
如果電腦有連接網路最有效率的方法就是直接連 Symbol Server,
srv*symbolstore
Microsoft's symbol store:
.sympath srv*http://msdl.microsoft.com/download/symbols
建議加上 Cahce:
.sympath cache*;srv*http://msdl.microsoft.com/download/symbols
cache* 是指把 symbol 檔存到 default 的本地端,下次就不用載一次。
2013年5月13日 星期一
Be cautious with strncpy_s
strncpy_s 的宣告如下:
注意 numberOfElements 一定要大於 count,
Ex:
char dst[6];
strncpy_s(dst, 6, "a long string", 5);
dst 必須保留一位置給結束字元(null terminator)。
否則有機會 crash。
2013年3月5日 星期二
把常用的 TortoiseSVN 功能整合進 Visual Studio
我們可以將 TortoiseSVN 常用的功能,如 Log 和 Blame 整合進 Visual Studio,
步驟如下:
開啟 VS -> Tools -> External Tools...
Command: C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
Arguments(Log): /command:log /path:"$(ItemPath)"
Arguments(Blame): /command:blame /path:"$(ItemPath)" /line:$(CurLine)
如此一來,就可以在 VS 上對某一段 code 做 Log 和 Blame 啦! 相當好用!
步驟如下:
開啟 VS -> Tools -> External Tools...
![]() |
| [External Tools] |
Command: C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
Arguments(Log): /command:log /path:"$(ItemPath)"
Arguments(Blame): /command:blame /path:"$(ItemPath)" /line:$(CurLine)
如此一來,就可以在 VS 上對某一段 code 做 Log 和 Blame 啦! 相當好用!
2013年3月4日 星期一
利用指令透過 Visual Studio 開啟指定檔案
我們可以在執行檔 C:/Program Files/Microsoft Visual Studio 8/Common7/IDE/devenv.exe
後面加上:
A.cpp /command "Edit.Goto 200"
或是
/edit A.cpp
兩者的差異是,前者會開啟新的 VS 並可指定行號,後者會用已開啟的 VS 做為編輯器,
但無法指定行號。
2013年1月7日 星期一
Visual Studio 專案設定檔的存放路徑
C:\Users\[UserName]\AppData\Local\Microsoft\VisualStudio\8.0\VCComponents.dat
裡面存放著 Include Dirs, Lib Dirs 等等的路徑,我們常常對於不同的專案會有
不同的設定,此時只要備份並覆蓋該檔即可。
裡面存放著 Include Dirs, Lib Dirs 等等的路徑,我們常常對於不同的專案會有
不同的設定,此時只要備份並覆蓋該檔即可。
2012年10月31日 星期三
利用 WM_GESTURE 寫出有 Touch 功能的程式
如果只想做出簡單的 PAN 功能,可透過接收 WM_TABLET_FLICK 訊息來達成,
其提供了八個方向,但在 Win8 上好像收不到這個訊息。
另外的替代方案是,在 Win7 以上的作業系統,我們可以透過接受 WM_GESTURE 來實作。
在使用前先透過 WM_GESTURENOTIFY 和 SetGestureConfig() 設定我們要或不要接收
哪些手勢。假如設定好只接受 PAN 的手勢後,即可在 WM_GESTURE 用 GetGestureInfo()
攔到 GESTUREINFO.dwID = GID_PAN 的資訊。
另外由 GESTUREINFO.dwFlags = GF_BEGIN/GF_INERTIA/GF_END 來分析起始點、慣性點和
終點。要注意的是,除非有明確的 PAN 動作(手指離開時的點需停留得夠久),否則
GF_BEGIN/GF_END 並不會成對出現,而會出現 GF_INERTIA 的慣性點。
GF_INERTIA 是用來實作像是拖曳卷軸時手已經放開的滑動效果。
其提供了八個方向,但在 Win8 上好像收不到這個訊息。
另外的替代方案是,在 Win7 以上的作業系統,我們可以透過接受 WM_GESTURE 來實作。
在使用前先透過 WM_GESTURENOTIFY 和 SetGestureConfig() 設定我們要或不要接收
哪些手勢。假如設定好只接受 PAN 的手勢後,即可在 WM_GESTURE 用 GetGestureInfo()
攔到 GESTUREINFO.dwID = GID_PAN 的資訊。
另外由 GESTUREINFO.dwFlags = GF_BEGIN/GF_INERTIA/GF_END 來分析起始點、慣性點和
終點。要注意的是,除非有明確的 PAN 動作(手指離開時的點需停留得夠久),否則
GF_BEGIN/GF_END 並不會成對出現,而會出現 GF_INERTIA 的慣性點。
GF_INERTIA 是用來實作像是拖曳卷軸時手已經放開的滑動效果。
2012年10月24日 星期三
改變 TextOut 時的字型或大小
我們可以利用 CreateFont() 和 CreateFontIndirect() 來產生 HFONT 物件。
hFont =
CreateFont(48,0,0,0,FW_DONTCARE,FALSE,TRUE,FALSE,DEFAULT_CHARSET,OUT_OUTLIN
E_PRECIS, CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY,
VARIABLE_PITCH,TEXT("Impact"));
然後再將此字型物件置換到 DC 上即可。
SelectObject(hDC, hFont);
TextOut(hDC, 0, 0, "Hello", lstrlen("Hello"));
Ref: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183499(v=vs.85).aspx
hFont =
CreateFont(48,0,0,0,FW_DONTCARE,FALSE,TRUE,FALSE,DEFAULT_CHARSET,OUT_OUTLIN
E_PRECIS, CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY,
VARIABLE_PITCH,TEXT("Impact"));
然後再將此字型物件置換到 DC 上即可。
SelectObject(hDC, hFont);
TextOut(hDC, 0, 0, "Hello", lstrlen("Hello"));
Ref: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183499(v=vs.85).aspx
畫出只有邊框的透明 Rectangle
我們只要在選擇筆刷時設 NULL_BRUSH 即可 :
SelectObject(hDC,GetStockObject(NULL_BRUSH));
Rectangle(hDC, 0, 0, 100, 100);
SelectObject(hDC,GetStockObject(NULL_BRUSH));
Rectangle(hDC, 0, 0, 100, 100);
2012年8月22日 星期三
程式相容性助理
在 Win7 或 Win8 上常常可以看到一些程式直行或關閉時,跳出程式相容性助理
(Program Compatibility Assistant) 的視窗,跳出的原因有很多種可以參考這篇,
http://msdn.microsoft.com/library/bb756937.aspx。若想透過程式的方法強制把 PCA 關掉,
可以在開發程式時的 Manifest 檔加上一些屬性,詳細可參考:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd371711(v=vs.85).aspx 。
(Program Compatibility Assistant) 的視窗,跳出的原因有很多種可以參考這篇,
http://msdn.microsoft.com/library/bb756937.aspx。若想透過程式的方法強制把 PCA 關掉,
可以在開發程式時的 Manifest 檔加上一些屬性,詳細可參考:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd371711(v=vs.85).aspx 。
2012年8月13日 星期一
[Win8] 以檔案開啟...
在 Win8 裡第一次執行文件或檔案時,會跳出你要用哪種檔案來開啟的小視窗,此時該檔案右
側的文字所顯示的即是檔案的描述(File Description)。在用 Visual Studio 開發 Windows App 時,
可從 Resource View 裡,找到專案的 Version\VS_VERSION_INFO 資源檔去做更改。
同時,這個值會被 cache 在 :
Path: HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\MuiCache
Name: C:\Windows\system32\mspaint.exe.FriendlyAppName
Data: Paint
側的文字所顯示的即是檔案的描述(File Description)。在用 Visual Studio 開發 Windows App 時,
可從 Resource View 裡,找到專案的 Version\VS_VERSION_INFO 資源檔去做更改。
同時,這個值會被 cache 在 :
Path: HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\MuiCache
Name: C:\Windows\system32\mspaint.exe.FriendlyAppName
Data: Paint
2012年6月20日 星期三
[MFC] 將使用者設定儲存到 Key 裡
通常一個較好的使用者介面,會在程式關閉時,將使用者的狀態紀錄到系統裡,
等下次使用者開啟軟體時,再將狀態讀出,顯示使用者關閉前的狀態,
而我們可以透過幾個 Windows API 做到這樣的功能。
CWinApp::GetProfileInt
CWinApp::GetProfileString
CWinApp::WriteProfileInt
CWinApp::WriteProfileString
原本這些 API 會將狀態寫到 C:\Windows\XXX.INI 裡,也從這裡讀,
但在 MSDN 上已說這不是個好的方式,建議存放到 Registry Key 裡。
透過 SetRegistryKey(LPCTSTR lpszRegistryKey) 可以指定存放到 Registry Key 而非 INI 檔。
存放的路徑如下:
HKEY_CURRENT_USER\Software\<company name>\<application name>\<section name>\<value name>.
等下次使用者開啟軟體時,再將狀態讀出,顯示使用者關閉前的狀態,
而我們可以透過幾個 Windows API 做到這樣的功能。
CWinApp::GetProfileInt
CWinApp::GetProfileString
CWinApp::WriteProfileInt
CWinApp::WriteProfileString
原本這些 API 會將狀態寫到 C:\Windows\XXX.INI 裡,也從這裡讀,
但在 MSDN 上已說這不是個好的方式,建議存放到 Registry Key 裡。
透過 SetRegistryKey(LPCTSTR lpszRegistryKey) 可以指定存放到 Registry Key 而非 INI 檔。
存放的路徑如下:
HKEY_CURRENT_USER\Software\<company name>\<application name>\<section name>\<value name>.
其實 SetRegistryKey 就是把 CWinAp::m_pszProfileName 成員變數設成你所設定的值,
2012年6月5日 星期二
把視窗移到最前面
試過了 BringToTop() 和 SetWindowsPos() 都沒什麼用。
SwitchToThisWindow() 有用,但不是想要的效果。
SetForegroundWindow() 有用,但不是每次都成功,
失敗時程式就會在工作列上閃阿閃的 (註 1)。
最後參考了這篇的第二段 code ,終於實現了需要的功能:
http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo
最主要是 AttachThreadInput() 讓 SetForegroundWindow() 幾乎都能成功。
註 1: 利用 SPI_SETFOREGROUNDFLASHCOUNT 可以控制要閃的次數。
SystemParametersInfo( SPI_SETFOREGROUNDFLASHCOUNT, 0, 5, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
SwitchToThisWindow() 有用,但不是想要的效果。
SetForegroundWindow() 有用,但不是每次都成功,
失敗時程式就會在工作列上閃阿閃的 (註 1)。
最後參考了這篇的第二段 code ,終於實現了需要的功能:
http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo
最主要是 AttachThreadInput() 讓 SetForegroundWindow() 幾乎都能成功。
註 1: 利用 SPI_SETFOREGROUNDFLASHCOUNT 可以控制要閃的次數。
SystemParametersInfo( SPI_SETFOREGROUNDFLASHCOUNT, 0, 5, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
2012年2月17日 星期五
讀寫 ini 檔
詳見 MSDN。
WritePrivateProfileString(szSection, szTag, szValue, szPath);
GetPrivateProfileString(szSection, szTag, NULL, szValue, MAX_PATH, szPath);
WritePrivateProfileString(szSection, szTag, szValue, szPath);
GetPrivateProfileString(szSection, szTag, NULL, szValue, MAX_PATH, szPath);
2012年1月19日 星期四
[DEBUG] ProcessMonitor 2.96
ProcessMonitor 可以幫助開發者查看特定應用程式正在執行時,所存取
的 RegKey 和檔案等等,是個相當方便的工具。
下面的網誌作者做了簡略的介紹:
http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/08/18/977.aspx
的 RegKey 和檔案等等,是個相當方便的工具。
下面的網誌作者做了簡略的介紹:
http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/08/18/977.aspx
2012年1月10日 星期二
[Win32] 自訂 Button 的顏色
在 Win32 的視窗程式設計下,想要自訂 Button 的顏色或 Button 文字的顏色,
並非易事,必須搭配 WM_DRAWITEM 來繪製自訂 Button。
1. 首先,在 Button 的 Properties Page 上將 Owner Draw 屬性設成 True。
2. 接收到 WM_DRAWITEM 訊息時繪製 Button 的樣式和欲顯示的字串。
2.1 利用 DrawEdge() 可繪製 Button 被按下和沒按的樣子。
2.2 DrawText() 可畫出文字,避免使用 SetWindowText(), 因為其會再觸發
WM_DRAWITEM 很容易造成無窮回圈,而導致 Stack overflow。
並非易事,必須搭配 WM_DRAWITEM 來繪製自訂 Button。
1. 首先,在 Button 的 Properties Page 上將 Owner Draw 屬性設成 True。
2. 接收到 WM_DRAWITEM 訊息時繪製 Button 的樣式和欲顯示的字串。
2.1 利用 DrawEdge() 可繪製 Button 被按下和沒按的樣子。
2.2 DrawText() 可畫出文字,避免使用 SetWindowText(), 因為其會再觸發
WM_DRAWITEM 很容易造成無窮回圈,而導致 Stack overflow。
訂閱:
文章 (Atom)

