你不能使用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事件,所以如果有任何處理器在你正試圖自動化的程序中編寫代碼,那麼它可能不會像用戶改變值那樣工作。