線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:6221
推到 Plurk!
推到 Facebook!

如何以SendMessage取代keybd_event??

尚未結案
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-02-25 10:16:38 IP:218.170.xxx.xxx 未訂閱
 
procedure TForm2.Button1Click(Sender: TObject);
begin
  Timer1.Enabled:=True;
  showmessage('111');
end;    procedure TForm2.Timer1Timer(Sender: TObject);
var H : THandle;
    ClassName : Array[0..255] of Char;
    P : TPoint;
begin
  Timer1.Enabled:=False;
  if IsIconic(Application.Handle) then ShowWindow(Application.Handle, SW_RESTORE)
  else begin
  end;
 SetForegroundWindow(Application.Handle);
// keybd_event(VK_RETURN, 0, 0, 0);
// keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);       H := Application.Handle;
   if H <> NULL then begin
      SendMessage(h, WM_KEYDOWN, VK_RETURN, (($1C shl 16) or 1));
      SendMessage(h, WM_CHAR, 13, (($1C shl 16) or 1));
      SendMessage(h, WM_KEYUP, VK_RETURN, (($1 shl 30) or ($1C shl 16) or 1));
   end;    {
   H := FindWindow(nil, '未命名 - 記事本');
   if H = 0 then begin
      ShowMessage('Not Found');
      exit;
   end;
   H := FindWindowEx(H, 0, 'Edit', nil);
   if H <> NULL then begin
      SendMessage(h, WM_KEYDOWN, VK_RETURN, (($1C shl 16) or 1));
      SendMessage(h, WM_CHAR, 13, (($1C shl 16) or 1));
      SendMessage(h, WM_KEYUP, VK_RETURN, (($1 shl 30) or ($1C shl 16) or 1));
   end;
}    end;
因為我的程式要在terminal下執行所以試過keybd_event不行..我想試試用 SendMessage是否可以..記事本已試過可以,可是自己寫的程式用SendMessage 卻試不出來.....請各位大大幫一下謝謝
shinjie
資深會員


發表:12
回覆:275
積分:287
註冊:2003-03-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-02-25 11:57:20 IP:61.59.xxx.xxx 未訂閱
剛剛測試了一下,因為SendMessage是依照你的Handle來傳送訊息,所以如果你是用Application.Handel的話,SendMessage會把訊息傳給Application,而如果你傳送的字元對整個Application沒有用的話,就不會出現你要的結果。 所以你必須跟記事本的用法一樣 H := FindWindowEx(H, 0, 'Edit', nil); 取得你要輸入字元介面的Handel,這樣才能出現你要的結果。
------
我將在茫茫人海中尋訪我唯一之靈魂伴侶。
得之;我幸。不得;我命。
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-02-25 12:24:50 IP:218.170.xxx.xxx 未訂閱
引言: 剛剛測試了一下,因為SendMessage是依照你的Handle來傳送訊息,所以如果你是用Application.Handel的話,SendMessage會把訊息傳給Application,而如果你傳送的字元對整個Application沒有用的話,就不會出現你要的結果。 所以你必須跟記事本的用法一樣 H := FindWindowEx(H, 0, 'Edit', nil); 取得你要輸入字元介面的Handel,這樣才能出現你要的結果。
// H := FindWindowEx(H, 0, 'Button', nil); // H := FindWindowEx(H, 0, 'Edit', nil); // H := FindWindowEx(H, 0, 'Memo', nil); 這我也試過..不行阿...有用Edit,Memo,button都收不到訊號阿!!! 我的需求是要給ForegroundWindow一個enter的按鍵訊號. 你試可以?可以給我程式碼嗎? 發表人 - shinhrn 於 2005/02/25 12:29:05
shinjie
資深會員


發表:12
回覆:275
積分:287
註冊:2003-03-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-02-25 13:26:02 IP:61.59.xxx.xxx 未訂閱
如果只是要傳一個enter的按鍵訊號,可以試試 PostMessage(H, WM_KEYDOWN, VK_RETURN, 0); 或是試試 H := FindWindow(nil, '未命名 - 記事本'); if H = 0 then begin ShowMessage('Not Found'); exit; end; if H <> NULL then begin BringWindowToTop(H); keybd_event(VK_RETURN, 0, 0, 0); keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0); end; 如果你要用原本的方法,那麼我也不清楚怎麼改說。
------
我將在茫茫人海中尋訪我唯一之靈魂伴侶。
得之;我幸。不得;我命。
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-02-25 13:43:28 IP:218.170.xxx.xxx 未訂閱
我已經說過了.. 記事本已試過可以,可是自己寫的程式用SendMessage卻試不出來..... 而且我會要用SendMessage是因為程式要在terminal下執行... 當你把terminal最小化時...keybd_event就失效了...因為 SetForegroundWindow(Application.Handle); 無效了!!!!
boson
中階會員


發表:74
回覆:155
積分:85
註冊:2004-07-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-02-25 16:04:00 IP:218.170.xxx.xxx 未訂閱
Application.Handle 是主程序視窗的 Handle, 不是元件的 Handle, 如果你要傳訊息給某一個元件, 就應該將該元件的 Handle 傳給 SendMessage 例如, 將 H := Application.Handle; 改為 H:=Memo1.Handle; 即可 附帶一提, FindWindowEx 由函數名稱可知, 它是取得 Window 的 Handle, 而不是取得 Component 的 Handle, 所以應該不能用來取得 Button,Edit,Memo 等等元件的 Handle (記事本的 Edit 部份, 可能是一個子視窗區域, 所以可用 FindWindowEx 取得其 Handle)
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-02-25 16:33:32 IP:218.170.xxx.xxx 未訂閱
引言: Application.Handle 是主程序視窗的 Handle, 不是元件的 Handle, 如果你要傳訊息給某一個元件, 就應該將該元件的 Handle 傳給 SendMessage 例如, 將 H := Application.Handle; 改為 H:=Memo1.Handle; 即可
a.原本我是想傳給Application,然後因為,Application的Focus是停在Memo1上, Application不是會再傳給Memo1嗎?我就是這樣想才會不行< >< > b.可以傳給memo1了...可是我要傳的是別人寫的程式...不知道元件名稱ㄝ.... 我的需求是要給ForegroundWindow一個enter的按鍵訊號...有辦法嗎? 發表人 - shinhrn 於 2005/02/25 16:35:47 發表人 - shinhrn 於 2005/02/25 16:45:24
chtai
高階會員


發表:68
回覆:238
積分:116
註冊:2004-05-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-02-25 17:01:41 IP:203.67.xxx.xxx 未訂閱
引言: a.原本我是想傳給Application,然後因為,Application的Focus是停在Memo1上, Application不是會再傳給Memo1嗎?我就是這樣想才會不行< >< > b.可以傳給memo1了...可是我要傳的是別人寫的程式...不知道元件名稱ㄝ.... 我的需求是要給ForegroundWindow一個enter的按鍵訊號...有辦法嗎?
shinhrn 您好, 底下是一篇小弟用 BCB 的心得, 希望能對您有所幫助 :) http://delphi.ktop.com.tw/topic.php?TOPIC_ID=64701 -- http://www.csie.nctu.edu.tw/~chtai/software.php 好用免費軟體的收集網頁,歡迎大家跟我分享或一同推廣免費軟體。 若您覺得這網頁不錯,也歡迎您將它傳出去 :)
------
My Web: http://nelson.csie.us
My Blog: http://blog.nelson.csie.us
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-02-25 19:03:49 IP:218.170.xxx.xxx 未訂閱
引言: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=64701
謝謝你這一篇我確實有參考到.... 可是我是的結果是 於delphi 中 H := FindWindowEx(H, 0, 'Edit', nil); 這一行是重點...沒找到對應的Handel,SendMessage就無效... 可是我的問題是不知道如何取得ForegroundWindowv現在輸入的是拿個Handel?? 因為我試過
 
  if IsIconic(Application.Handle) then ShowWindow(Application.Handle, SW_RESTORE)
  else begin
  end;
  SetForegroundWindow(Application.Handle);
   H :=GetForegroundWindow();
   H := FindWindowEx(h, 0, nil, nil);
   if H <> NULL then begin
      PostMessage(h, WM_KEYDOWN, VK_RETURN, (($1C shl 16) or 1));
      PostMessage(h, WM_CHAR, 13, (($1C shl 16) or 1));
      PostMessage(h, WM_KEYUP, VK_RETURN, (($1 shl 30) or ($1C shl 16) or 1));
   end;    
可以... 可是我要傳給自己的程式時,不是可以這樣寫嗎?卻沒反應ㄝ
   H := FindWindowEx(Application.Handle, 0, nil, nil);
   if H <> NULL then begin
      PostMessage(h, WM_KEYDOWN, VK_RETURN, (($1C shl 16) or 1));
      PostMessage(h, WM_CHAR, 13, (($1C shl 16) or 1));
      PostMessage(h, WM_KEYUP, VK_RETURN, (($1 shl 30) or ($1C shl 16) or 1));
   end;
boson
中階會員


發表:74
回覆:155
積分:85
註冊:2004-07-31

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-02-25 23:05:55 IP:218.170.xxx.xxx 未訂閱
引言: 可是我要傳給自己的程式時,不是可以這樣寫嗎?卻沒反應ㄝ H := FindWindowEx(Application.Handle, 0, nil, nil); if H <> NULL then begin PostMessage(h, WM_KEYDOWN, VK_RETURN, (($1C shl 16) or 1)); PostMessage(h, WM_CHAR, 13, (($1C shl 16) or 1)); PostMessage(h, WM_KEYUP, VK_RETURN, (($1 shl 30) or ($1C shl 16) or 1)); end;
我試了上面這一段程式是可以執行的, 只不過當輸入焦點落在 Button 上時, 可以 但若輸入焦點落在 Memo 上時, 則不行 就此看來, 或許問題出在 PostMessage 的第三與第四個參數上 發表人 - boson 於 2005/02/25 23:06:56
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-02-26 15:18:37 IP:218.170.xxx.xxx 未訂閱
引言: 我試了上面這一段程式是可以執行的, 只不過當輸入焦點落在 Button 上時, 可以 但若輸入焦點落在 Memo 上時, 則不行 就此看來, 或許問題出在 PostMessage 的第三與第四個參數上
沒錯...如果你再貼一個edit元件來試試就更有趣了 PostMessage(h, WM_CHAR, $41, 0); //加一個A字元上去 你就會發現button 收到enter,edit收到A字元; 我的需求是要給ForegroundWindow一個enter的按鍵訊號,不管它停在拿個元件 上就是送給他enter用,不知道是否可以?
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-02-26 18:51:51 IP:203.69.xxx.xxx 未訂閱
引言: 我的需求是要給ForegroundWindow一個enter的按鍵訊號,不管它停在拿個元件 上就是送給他enter用,不知道是否可以?
既然這樣。 你會寫送訊。而目標程式也可以動作了。 那你要不要再多試試 winsight32 這個工具程式? 看看 setfocus 這樣的動作先把 FOCUS 設到你要輸入的地方? 還是你要在你的目標程式做KEY攔捷的動作? 把按鍵攔下來,然後丟進你要輸入的地方? 因為,當大家解決了你現在這個 ENTER問題時。 也許。你又會問,那個ENTER要在最後面。而不是在最前面或中間出現。 這類的問題。 所以。你的解法只有 收到KEY->設定FOCUS->移動游標到你要的地方->加入KEY。 就這樣而已。 加油。
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-03-02 08:58:14 IP:218.170.xxx.xxx 未訂閱
 
  if IsIconic(Application.Handle) then ShowWindow(Application.Handle, SW_RESTORE)
  else begin
  end;
  SetForegroundWindow(Application.Handle);
  
  
a.  
  keybd_event(VK_RETURN, 0, 0, 0);
  keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
b.
   H := FindWindowEx(H, 0, 'Edit', nil);
   if H <> NULL then begin
      SendMessage(h, WM_KEYDOWN, VK_RETURN, (($1C shl 16) or 1));
      SendMessage(h, WM_CHAR, 13, (($1C shl 16) or 1));
      SendMessage(h, WM_KEYUP, VK_RETURN, (($1 shl 30) or ($1C shl 16) or 1));
   end;
1.ab兩種方式在單機無人操作時均可以,可是如果執行剛好有mouse在操作別的作業時就無效 <>>
shinhrn
中階會員


發表:54
回覆:165
積分:83
註冊:2002-06-05

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-03-07 15:15:28 IP:218.170.xxx.xxx 未訂閱
謝謝各位的回答,大致上已可以   SetForegroundWindow(Application.Handle);   HWND2 := GetActiveWindow;   HWND1 := GetParent(HWND2);   if HWND1=Handle then   begin     SendMessage(HWND2,WM_CLOSE,0,0);   end; 這是我現在用的方式,現在遇到的困難是,如何取得ap本身的ActiveWindow(因為我想要程式可以背景作業,所以不可以用GetActiveWindow),我將另開主題討論...謝謝
gszxs
一般會員


發表:0
回覆:1
積分:0
註冊:2005-04-19

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-04-23 22:24:33 IP:222.84.xxx.xxx 未訂閱
谢谢老兄发了此贴,本人也一直寻求向非当前活动窗口发送按键消息的方法,因为本人做的是最简单的动作式游戏外挂,但同时不想只是简单的按键精灵用法,想让放在后台的游戏窗口能接收到按键消息,如果是前台的话,因为主窗口具有焦点输入,所以findwindow()获得的游戏窗口可以接收到postmessage发送的按键 消息,但当窗口成为后台时,失去输入焦点,就无效了,不知道真正获得焦点的是游戏窗口下的哪个子窗口。 本人联系方式:gszxs@21cn.com如老兄找到解法请传授下经验,感激不尽!!!
系統時間:2024-05-18 6:14:58
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!