[C#]程式幫您按按鈕(SendKey & SendMessage)
十二月 6, 2008
前言
專案中有個程式負責透過 ACDSee 列印(ProcessStartInfo.Verb=”Print”)各種圖檔。但 ACDSee 在列印時會出現讓使用者設定格式、頁首頁尾、印表機選項的視窗出現,要按下「列印(P)」之後才會真的開始列印,所以程式必須在開始工作時偵測 ACDSee 的狀態並且按下列印鈕。
方法如下:
- hWnd = FindWindow(null,”ACDSee – 列印”); // 尋找 ACDSee 的列印視窗
- SetForegroundWindow(hWnd); // 將視窗帶到前景
- SendKeys.SendWait(“{ENTER}”); // 送出 ENTER 鍵按列印鈕
事前測試都OK,但安裝到客戶的機器上卻經常發生沒有自動按列印鈕而卡住的問題。原以為是被其它程式干擾{ENTER}的發送,但奇怪的是同事在現場怎麼測試都無法重現問題,一離開不久客戶就反應問題又發生了。
最後,細心的同事發現是因為機器一段時間沒人操作就會被鎖住(lock),流程卡住的問題就開始了!
推測:當系統 lock 時,畫面看不到 ACDSee 的視窗(但 FindWindow 可以找到)所以 SendKey 無法送到正確的視窗。
解法
用 SendMessage 發送 WM_COMMAND
程式(C版)
HWND hWnd = ::FindWindow(NULL, "ACDSee - Print");
if(NULL != hWnd)
{
HWND hButton = ::FindWindowEx(hWnd, NULL, "BUTTON", "&Print");
if(NULL != hButton)
{
::PostMessage(hWnd, WM_COMMAND, MAKEWPARAM(::GetDlgCtrlID(hButton), BN_CLICKED),(LPARAM)hButton);
}
else
{
AfxMessageBox("Can not find [Print]");
}
}
else
{
AfxMessageBox("Can not find [ACDSee - Print]");
}
程式(C#版)
IntPtr hWnd = FindWindow(null, "ACDSee - 列印");
if ( !hWnd.Equals(IntPtrZero) )
{
IntPtr hButton = FindWindowEx(hWnd, 0, "BUTTON", "列印(&P)");
if ( !hButton.Equals(IntPtrZero) )
{
SendMessage(hWnd, WM_COMMAND, GetDlgCtrlID(hButton) , hButton);
} // if
} // if
/* API 定義*/
[DllImport("User32.dll",EntryPoint="FindWindow")]
private static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
[DllImport("User32.dll")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, int hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll")]
public static extern int GetDlgCtrlID(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "SendMessageA")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, IntPtr lParam);
private const int WM_COMMAND = 0x111;
private const int BN_CLICKED = 0;
相關文章
- 無
Leave a Reply