c#本身是沒有findwindow這個函式的,
為什麼沒有呢?
很簡單,c#畢竟是微軟自家開發出來的。而win api中本來封裝了很多對視窗的操作,所以當然能重用的就要重用,這些封裝好的函式一般在系統dll中。
那應該要怎麼在c#中呼叫封裝好的dll呢?
這就要用到c#中的乙個屬性類 dllimport,dllimport位於命名空間system.runtime.interopservices;
using system.runtime.interopservices;
顧名思義,dllimport就是用來
匯入dll的,使用方法如下:
[dllimport("user32.dll
", entrypoint = "
findwindow
", charset =charset.auto)]
private
extern
private static intptr findwindow(string classname, string
captionname);
[dllimport(
"user32.dll
", entrypoint = "
findwindowex
", charset =charset.auto)]
private
extern
static intptr findwindowex(intptr parent, intptr child, string classname, string
captionname);
[dllimport(
"user32.dll")]
static
extern intptr sendmessage(intptr hwnd, uint32 msg, intptr wparam, [marshalas(unmanagedtype.lpstr)] string
lparam);
[dllimport(
"user32.dll
", entrypoint = "
sendmessagea")]
private
static
extern
int sendmessage(intptr hwnd, int wmsg, int
wparam, stringbuilder lparam);
[dllimport(
"user32.dll
", entrypoint = "
sendmessage
", setlasterror = true, charset =charset.auto)]
private
static
extern
int sendmessage(intptr hwnd, uint wmsg, int wparam, int
lparam);
[dllimport(
"user32.dll")]
static
extern intptr sendmessage(intptr hwnd, uint32 msg, intptr wparam, [marshalas(unmanagedtype.lpstr)] string
lparam);
[dllimport(
"user32.dll
", entrypoint = "
sendmessagea")]
private
static
extern
int sendmessage(intptr hwnd, int wmsg, int wparam, stringbuilder lparam);
雖然樣子看著有點吃藕,但還是非常實用的;
從引用的結構可以看出,引入的函式類似於宣告,所以我們只要把上面那段**新增到類中定義成員變數的地方即可;
//這就是用來查詢要控制的應用程式視窗的
//classname就是要查詢視窗的類,一般設定為null即可
//captionname就是要查詢的視窗的名稱
findwindow(string classname, string
captionname);
//這是用來查詢視窗中的控制項的
//parent就是父視窗控制代碼,就是呼叫findwindow的返回值
//child就是子視窗控制代碼(因為如果根據classname進行查詢的話,會找到很多結果,可以根據子控制代碼精確定位)
//classname就是要查詢的視窗的類,如果根據captionname進行查詢的話則設定為null即可
//captionname為查詢的控制項的標題(如果是按鈕則是按鈕上的文字)
findwindowex(intptr parent, intptr child, string classname, string captionname);
呼叫了上面的兩個函式之後,我們已經可以找到受控的應用程式視窗了;
接下來就是要進行最重要的一步了;
就是通過sendmessage給受控方傳送訊息:
//三個函式的賣相都是差不多的,除了第四個函式//第乙個引數為findwindowex找到的控制項的控制代碼
//第二個引數為要傳遞的訊息型別
//第三個引數如果你引入時引入型別為uint或int,如果不獲取則設為0即可
//如果引入時為intptr則設為intptr.zero,兩者並沒有什麼區別
[dllimport("
user32.dll
", entrypoint = "
sendmessage
", setlasterror = true, charset =charset.auto)]
private
static
extern
int sendmessage(intptr hwnd, uint wmsg, int wparam, int
lparam);
[dllimport(
"user32.dll")]
private
static
extern intptr sendmessage(intptr hwnd, uint32 msg, intptr wparam, [marshalas(unmanagedtype.lpstr)] string
lparam);
[dllimport(
"user32.dll
", entrypoint = "
sendmessagea")]
private
static
extern
int sendmessage(intptr hwnd, int wmsg, int wparam, stringbuilder lparam);
關鍵是第四個引數,那麼他們有什麼不同呢:
//第四個看著就和第三個引數差不多
//所以這引數不用看也知道肯定是0的
//它一般是用於模擬點選按鈕的
sendmessage(intptr hwnd, uint wmsg, int wparam, int lparam);
//[marshalas(unmanagedtype.lpstr)]看著有點嚇人//但其實他只是把string強制轉換為字串指標
//方便用於在程式間傳遞資料
//而我們使用時只要傳入string即可
sendmessage(intptr hwnd, uint32 msg, intptr wparam, [marshalas(unmanagedtype.lpstr)] string lparam);
//stringbuilder就是可變字串//這個過載函式與前兩個不相同的地方除了最後乙個引數還有第三個引數
//第三個引數不再設為0
//而是要讀取的字串的長度
sendmessage(intptr hwnd, int wmsg, int wparam, stringbuilder lparam);
反射簡單呼叫
1 class program 2 構造函式呼叫有參建構函式 16object obj constructor.invoke new object 17 methodinfo method1 type.getmethod sayname 得到無參公有方法 18 methodinfo method2 ...
C 簡單呼叫Sqlite函式(一)
sqlite是遵守acid的關聯式資料庫管理系統,它包含在乙個相對小的c庫中。它是d.richardhipp建立的共有領域專案。sqlite官方原始碼不支援加密解密,資料庫檔案中的資料以全明文的形式存 在。不過作者顯然仔細考慮過這個問題,留下了實現加密的介面。sqlite api簡介 1 其中sql...
簡單呼叫部署在鏈上的合約
submitted for verification at etherscan.io on 2019 06 10 pragma solidity 0.5.0 pragma experimental abiencoderv2 spdx license identifier gpl 3.0 title ...