2011-07-05 40 views
0

我嘗試使用了AutoIt自動在第三方.NET應用程序填寫表格日曆日期選擇。的AutoIt:自動在第三方.NET應用程序

我遇到了一些麻煩設置在一個日曆控件的日期。

這我目前正在嘗試填充控制類類型WindowsForms10.SysDateTimePick32.app.0.378734a的,根據AutoIt3窗口信息。最初我只是試着將控件的文本設置爲我想要的日期,但是這根本就沒有做任何事情。

然後我試圖使用_GUICtrlMonthCal_SetCurSel,但是,正如所有的,我曾嘗試使用其他_GUI*功能,這絲毫也不做任何事情(正確的頭球攻門被包括在內,它只是沒有當我做任何事跑了)。

沒有人有任何想法如何,我會去這樣做呢?

感謝, 裏克

回答

1

你不能使用GUICtrlMonthCal *功能的原因是因爲你面對的不是一個月/壓延機的控制。在.NET中他們確實有它們,但在這種情況下,它是一個DateTimePicker。

DateTimePickers確實有在下拉列表中MonthCalender雖然下跌,但是當你點擊下拉所以很難直接控制它會出現在這個被創建。相反,我看了看,當程序將通過建立一個小的測試案例的價值會發生什麼......這是我發現的消息:

<00001> 00090572 S WM_GETTEXTLENGTH 
<00002> 00090572 R WM_GETTEXTLENGTH cch:12 
<00003> 00090572 S WM_GETTEXT cchTextMax:26 lpszText:05E8D51C 
<00004> 00090572 R WM_GETTEXT cchCopied:12 lpszText:05E8D51C ("0") 
<00005> 00090572 S message:0x1002 [User-defined:WM_USER+3074] wParam:00000000 lParam:01F6A2A8 
<00006> 00090572 R message:0x1002 [User-defined:WM_USER+3074] lResult:00000001 
<00007> 00090572 S WM_GETTEXTLENGTH 
<00008> 00090572 R WM_GETTEXTLENGTH cch:12 
<00009> 00090572 S WM_GETTEXT cchTextMax:26 lpszText:05E8D51C 
<00010> 00090572 R WM_GETTEXT cchCopied:12 lpszText:05E8D51C ("0") 
<00011> 00090572 P WM_PAINT hdc:00000000 
<00012> 00090572 S WM_ERASEBKGND hdc:54010EE3 
<00013> 00090572 R WM_ERASEBKGND fErased:True 

最有意思的還有用戶自定義的消息,該消息控件通常會如何獲取對他們來說唯一的消息。如果我們假設我正確的是0x1002設置了數據,那麼仍然要做的唯一事情就是看看lParam的含義。這可能會很棘手,因爲您將該值設置爲DateTime對象。

我要做的下一件事是檢查ildasm來看看System.Windows.Forms.DateTimePicker :: set_Value,因爲我想這會告訴你很多有關.NET如何做它...我會做一些更多的研究和更新這篇文章。

第2部分:好的,所以set_Value的反彙編做了我所說的...它將DateTime轉換爲他們使用DateTimeToSysTime調用「System」時間的東西......雖然不公開可見,但您可以大致看到它在做什麼的反彙編......但它更容易簡單地假設它使用標準的WinAPI的SYSTEMTIME結構here。這是一個相當的閱讀,但你需要填補其中的一個結構。

然後,我們可以做出相當安全的假設lParam的,我們希望在消息中是一個指向SYSTEMTIME結構...我會對其進行測試,並更新帖子:)

第3部分:現在爲激動人心的部分...讓它在實踐中工作。第一個問題是我們不能在使用SendMessage的應用程序之間移動指針,所以我們需要一些額外的代碼來在另一個程序中創建一個緩衝區。除此之外,它的工作完全像我期望:

#Include <GuiMonthCal.au3> ; $tagSYSTEMTIME is defined in here. 

Local $tSI = DllStructCreate($tagSYSTEMTIME) 

Local $hControl = ControlGetHandle("Date/Time Picker", "", "[NAME:ExampleDateTimePicker]") 
If @error Then Exit 0 * MsgBox(16, "Error", "Demo control not found.") 

; Fill the structure to current date/time using GetLocalTime 
DllCall("kernel32.dll", "none", "GetLocalTime", "ptr", DllStructGetPtr($tSI)) 
If @error Then Exit 0 * MsgBox(16, "Error", "GetLocalTime failed.") 

; Change the year 
DllStructSetData($tSI, "Year", 2005) 

; The struct needs to be in the process memory, so it's a bit of a workaround. 
Local $tMemMap 
Local $pMemory = _MemInit($hControl, DllStructGetSize($tSI), $tMemMap) 
_MemWrite($tMemMap, DllStructGetPtr($tSI)) 
$iRet = _SendMessage($hControl, 0x1002, 0, $pMemory, 0, "wparam", "ptr") 
_MemFree($tMemMap) 

當您運行的日期部分應改爲2005年。唯一的問題是,它不會觸發OnValueChanged事件,所以如果有任何處理器在你正試圖自動化的程序中編寫代碼,那麼它可能不會像用戶改變值那樣工作。