.Introduction
在開發程式中, 當碰到底層功能沒開放出來的時候, 往往最後只能在外部控制介面來處理,舉個例子, 像是碰到比較特殊的硬體裝置, 而廠商沒提供driver的原始碼, sdk的功能不完整等等問題之類的, 在只有官方的控制用應用程式的情況下, 此時也就只能寫外部程式直接來控制,以下論述實作方式.
首先, 如下圖, 拿一個列印介面來當例子, 主要步驟有兩個部分, 首先要先取得視窗控制元件,在來世更進一步的做控制.
列印程式介面
I. Get Window HWND
要取得一個windows的控制權, 首先要取得該視窗的HWND, 實作上可以使用FindWindow函式, 詳細可以看msdn.
FindWindow:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499%28v=vs.85%29.aspx
由函式的定義來看, 可以指定的參數有兩個, 一個是class名稱, 指定控制元件的類別,此部分不給也可以, 但是要防止碰到名稱一樣的控制元件,第二個是控制元件名稱, 以這個例子就是"列印", 程式碼如下
?
1
2
3
4
5
HWND wnd = FindWindow( NULL, "列印");
if(wnd)
{
//處理
}
II.對視窗做控制
在視窗的控制方面, 有兩種方式, 以下個別做說明
如果可以確定元件id的話, 可以Send WM_COMMAND做處理
抓到最底層目標的原件, 直接送訊息
1.WM_COMMAND
在這邊特別說明一下 WM_COMMAND, 當我們在做視窗操作時, 像是按下按鈕, 下拉選單等等, 都會觸發WM_COMMAND, 如果知道操作對象的話,某種程度直接使用WM_COMMAND就可以處理了, 詳細可以看msdn
WM_COMMAND:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms647591%28v=vs.85%29.aspx
WM_COMMAND的訊息有三種方式
Menu
Accelerator
Control
其中Accelerator不討論,這邊看menu以及Control的方式
.WM_COMMAND - Menu
實際測試了一下, 按鈕的話照menu方式直接送ID也有BN_CLICKED的效果,非按鈕的我就不確定了, 程式碼如下.
?
1
SendMessage(wnd, WM_COMMAND, IDOK, NULL);
參考程式碼頁面,照定義送的是menu元件的話, 則wParam的高位元會是0, 低位元是id, 其實等同IDOK(送高位元放0, 低位元IDOK), 如果怕判斷會出問題的話, 可以用MAKEWPARAM即可
?
1
2
3
4
5
6
7
WPARAM MAKEWPARAM(
WORD wLow,
WORD wHigh
);
WPARAM wParam = MAKEWPARAM( IDC_OK, 0);
SendMessage(wnd, WM_COMMAND, MAKEWPARAM(IDOK,0),0);
.WM_COMMAND - Control
Control的方式較複雜, 以下是msdn的定義
wParam
高位元放Control-defined notification code
低位元放Control identifier
lParam
Handle to the control window
此例已知控制視窗的wnd, 所以處理wParam即可
?
1
SendMessage(wnd, WM_COMMAND, MAKEWPARAM(IDOK,BN_CLICKED),0);
2.抓最底層目標元件
目前已取得目標視窗的HWND, 要在更進一步找視窗裡面的元件時, 需要使用FindWindowEX來處理, 使用方式一樣是由名稱找, 這邊範例指定class名稱, 名稱定義詳細可以看msdn, 這邊就不詳述了, 程式碼如下
?
1
2
3
HWND wndButton = FindWindowEx(wnd, NULL,"Button", "取消");;
SendMessage(wndButton, BM_CLICK, 0, 0);
III.實作程式碼
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void main()
{
HWND wnd = FindWindow( NULL, "列印");
if(wnd)
{
//方式1..知道元件ID的話可以用,
//物件是按鈕的話,直接送ID也可以達到Click的效果
//另外, 如果真的不確定id,
//IDOK(1)通常會是windows預設介面的"確定",IDCANCEL同
//menu方式
SendMessage(wnd, WM_COMMAND, IDOK, NULL);
SendMessage(wnd, WM_COMMAND, MAKEWPARAM(IDOK,0),0);
//Control方式
SendMessage(wnd, WM_COMMAND, MAKEWPARAM(IDOK,BN_CLICKED),0);
//方式2, 進一步取得按鈕, 送出按下訊息
HWND wndButton = FindWindowEx(wnd, NULL,"Button", "取消");//"列印(&P)");
if(wndButton)
{
SendMessage(wndButton, BM_CLICK, 0, 0);
}
}
}
http://arkkk.blogspot.tw/2011/11/findwindow-sendmessage.html
https://www.google.com.tw/search?q=VBA+%22%E8%99%95%E7%90%86%E7%A8%8B%E5%BA%8F%E8%AD%98%E5%88%A5%E7%A2%BC%22&oq=VBA+%22%E8%99%95%E7%90%86%E7%A8%8B%E5%BA%8F%E8%AD%98%E5%88%A5%E7%A2%BC%22&gs_l=serp.3...28672.33460.0.33712.5.5.0.0.0.0.168.400.3j2.5.0....0...1c.1.64.serp..0.0.0.xs22cvv6zWA
璉璉 2006-06-03 09:51:56 UTC
PermalinkRaw Message
VBA:
? Hex(Asc("心")) ' Big5
A4DF
? Hex(AscW("心")) ' Unicode
5FC3
所以用 VBA 包一個函數:
Function MyAsc(ByVal strChar As String) As String
MyAsc = Hex(Asc(strChar))
End Function
在工作表用
=MyAsc(A1)
http://microsoft.public.tw.excel.narkive.com/t730ls1c/big-5
https://www.youtube.com/watch?v=kcxK2xw6N0g
https://msdn.microsoft.com/zh-tw/library/s2dy91zy.aspx
http://www.programmer-club.com.tw/ShowSameTitleN/vb/21620.html
Clipboard - 存取剪貼簿
« 於: 2005-09-03, 17:33:42 »
DataObject 是應用程式和剪貼簿(Clipboard)之間的橋樑,
可以透過 DataObject 物件存取剪貼簿的內容。
DataObject 內容會隨著應用程式關閉而消失,
而剪貼簿內容則只要不離開Windows就不會消失。
以下程式會宣告並用到 DataObject 物件型態,
使用前必須確定已引用 MS Forms 2.0 Object Library。
(設定引用程式庫的方式請參考下圖)
Sub 取得剪貼簿內容()
Dim data As New DataObject
data.GetFromClipboard
Range("A1") = data.GetText(1)
End Sub
Sub 寫入剪貼簿()
Dim data As New DataObject
chars = [A1].Characters(3, 5).Text '取得A1部份內容
data.SetText chars '寫入DataObject
data.PutInClipboard '寫入剪貼簿
[B1].Select
ActiveSheet.Paste '再貼到B1
End Sub
Sub 清除剪貼簿內容()
Dim data As New DataObject
Set data = New DataObject
data.SetText ""
data.PutInClipboard
End Sub
你可以對 DataObject 使用 Clear 方法來清除它的內容,
但這方法在這裡並不實際,
不如直接傳送一個空字串到剪貼簿裡,如上面範例。
[附件已被管理員刪除]
http://gb.twbts.com/index.php?PHPSESSID=652f99d86b969ff33dc97941def91e52&topic=1878.msg9449#msg9449
https://www.google.com.tw/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=vba+%E5%89%AA%E8%B2%BC%E7%B0%BF+%E6%B8%85%E9%99%A4
Where is Microsoft Forms 2.0 Object Library?
Search your PC for the FM20.DLL file.
On my PC it is under C:\WINDOWS\system32
https://www.mrexcel.com/forum/excel-questions/482637-excel-2010-where-microsoft-forms-2-0-object-library.html
https://www.google.com.tw/search?q=MS+Forms+2.0+Object+Library&oq=MS+Forms+2.0+Object+Library&aqs=chrome..69i57&sourceid=chrome&ie=UTF-8
ActiveDocument.Content.ListFormat.ConvertNumbersToText