none
[VB 2010] Sendkeys 問題 RRS feed

  • 問題

  • hi,各位。

     Dim p = Process.GetProcessesByName("notepad")
      If p.Count > 0 Then
       calculatorhandle = p(0).MainWindowHandle
       SetWindowPos(calculatorhandle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE)
       SendKeys.Send("{F5}")
      End If
    

    我寫了個sendkeys在notepad上它是有反應的,

    但把notepad轉成其他應用程式時,它卻沒有反應,但在這程式上,我按F5是有反應的~

    所以,我想問一下為什麼會這樣?有無有解決的辦法?

    2010年11月3日 下午 03:25

解答

  • 沒有絕對的方法,如果你某個視窗正在輸入,很多都會破功~

    我用到的:

    0. GetForegroundWindow (API ,檢查視窗是否在最上方)

    1. AppActivate (VBNET 內建)

    2. SendMessage(hWnd, WindowMessages.WM_ACTIVATE, 2, 0)

    3. ShowWindow(hWnd, ShowWindowCommands.SW_SHOW)

    4. SetForegroundWindow(hWnd)

    5. 用 Me.Focus() 搶視焦後再轉。

    6. SetWindowPos(hWnd, HandleWindowSpecial.HWND_TOP, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE Or SetWindowPosFlags.SWP_NOSIZE Or SetWindowPosFlags.SWP_SHOWWINDOW)

    7. 鍵盤模擬

    其他:

    SetFocus (API ,需要先將執行緒加入:AttachThreadInput)

     


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    • 已標示為解答 CarbonDiarox 2010年11月7日 上午 09:29
    2010年11月5日 下午 03:18

所有回覆

  • dear

    你可先確定你所謂"其他應用程式"的名稱是否正確,名稱必須要與工作管理員的處理程序相同。

    Dim
     p = Process.GetProcessesByName("notepad"
    )

    例如:筆記本在工作管理員的名稱就是"notepad"


    秘訣無它,唯勤而已
    2010年11月3日 上午 07:51
  • hihi,

    to章:這個問題我有想過,但我覺得沒可能,因為如果名稱出錯,setwindowpos不會有反應,但setwindowpos有反應,但F5不作用。不過謝謝你的題示

    to joe,

    謝謝,我會try一下。

    2010年11月3日 下午 01:51
  • 我有個不情之請,因為我不太明,請問可以把程式碼給我嗎?
    2010年11月3日 下午 02:58
  • 請不要重複或跨區發文, 有先看過論壇的發文規定嗎 ? 你難道沒想過之前發的那一篇為何會被刪文嗎 ?

    張貼文章應注意事項及應提供資訊



    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2010年11月3日 下午 03:44
    版主
  • 因為並不是任何情況都可以透過 SetWindowPos 拉到最上層。

    API 相關的有四個,VBNET 內建指令有一個,還可以考慮 Key 模擬,我目前用的就六種。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年11月3日 下午 04:07
  • to bill :其實一開始我貼錯區,很抱歉,這是我的失誤,當我發完第2貼時,發現原來的貼無法Delete,所以會有這種情況,所以,如果可以的話,請幫我Delete另外那區的那張貼,謝謝。

    2010年11月4日 上午 02:32
  • 因為並不是任何情況都可以透過 SetWindowPos 拉到最上層。

    API 相關的有四個,VBNET 內建指令有一個,還可以考慮 Key 模擬,我目前用的就六種。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。


    其實,我想該視窗能變成"被選取"狀態應該足夠了。

    那麼,如果要把視窗拉到最上層要怎樣做?拉到上層(Topmost之下),但又要是被選取狀態那要怎樣做?

    2010年11月5日 上午 06:32
  • 2010年11月5日 上午 06:56
  • 何不使用SendMessage與PostMessage,這樣一來就算視窗不在最上層也能處理
    秘訣無它,唯勤而已
    2010年11月5日 上午 07:35
  • 感謝各大大題示~

    但我還不是太明~

    SendMessage 是API ?

    要怎樣把按鍵(例如:A / Alt / F5 etc)send到目標視窗(例如xxx.exe)中?

    2010年11月5日 上午 09:21
  • dear,

    SendMessage與PostMessage都是api

    Joe Hung <abbr class="affil">不是有回貼子嗎..你何不動手試一下?
    </abbr>

    再提供一個小範例
    http://www.dotblogs.com.tw/yc421206/archive/2009/07/06/9142.aspx


    秘訣無它,唯勤而已
    2010年11月5日 上午 09:30
  • to余~~

    我有試過 Joe Hung 給的提示,上面有constant,但我不知F5,alt,A 那些const的代碼。我還未找到那裡可以找到這些代碼

    http://www.programmer-club.com.tw/ShowSameTitleN/vbdotnet/9946.html

     '常數
        Const WM_KEYDOWN = &H100
        Const WM_KEYUP = &H101
        Const WM_CLOSE = &H10
        Const VK_RETURN = &HD

    你的題示 http://www.dotblogs.com.tw/yc421206/archive/2009/07/06/9142.aspx 都不錯,是一個參考,可惜跟Menu無什麼關係,只有findwindow用得著。

    不過,還是感謝你~~



    2010年11月5日 上午 10:22
  • to余~~

    我有試過 Joe Hung 給的提示,上面有constant,但我不知F5,alt,A 那些const的代碼。我還未找到那裡可以找到這些代碼

    http://www.programmer-club.com.tw/ShowSameTitleN/vbdotnet/9946.html

     '常數
        Const WM_KEYDOWN = &H100
        Const WM_KEYUP = &H101
        Const WM_CLOSE = &H10
        Const VK_RETURN = &HD

    你的題示 http://www.dotblogs.com.tw/yc421206/archive/2009/07/06/9142.aspx 都不錯,是一個參考,可惜跟Menu無什麼關係,只有findwindow用得著。

    不過,還是感謝你~~



    這只是要演示給你看用SendMessage或PostMessage的好處,它可以不用把視窗提到最前面,

    只要找的到控件的handle就能對它發送命令。


    秘訣無它,唯勤而已
    2010年11月5日 下午 03:17
  • 沒有絕對的方法,如果你某個視窗正在輸入,很多都會破功~

    我用到的:

    0. GetForegroundWindow (API ,檢查視窗是否在最上方)

    1. AppActivate (VBNET 內建)

    2. SendMessage(hWnd, WindowMessages.WM_ACTIVATE, 2, 0)

    3. ShowWindow(hWnd, ShowWindowCommands.SW_SHOW)

    4. SetForegroundWindow(hWnd)

    5. 用 Me.Focus() 搶視焦後再轉。

    6. SetWindowPos(hWnd, HandleWindowSpecial.HWND_TOP, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE Or SetWindowPosFlags.SWP_NOSIZE Or SetWindowPosFlags.SWP_SHOWWINDOW)

    7. 鍵盤模擬

    其他:

    SetFocus (API ,需要先將執行緒加入:AttachThreadInput)

     


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    • 已標示為解答 CarbonDiarox 2010年11月7日 上午 09:29
    2010年11月5日 下午 03:18
  • 補充:請問這種常數可以在那裡找到?

    Const WM_KEYDOWN = &H100
    Const WM_KEYUP = &H101
    Const WM_CLOSE = &H10
    Const VK_RETURN = &HD

    2010年12月15日 上午 05:41
  • 補充:請問這種常數可以在那裡找到?

    Const WM_KEYDOWN = &H100
    Const WM_KEYUP = &H101
    Const WM_CLOSE = &H10
    Const VK_RETURN = &HD


    檔案就在你身邊:

    C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinUser.h


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年12月15日 下午 02:21
  • 沒這個檔案XD,到Include那邊就沒有了~
    2010年12月16日 上午 05:27
  • 沒有表示你沒有完整安裝,你隨時可以到微軟下載中心抓 Microsoft SDK ,這裡面有很多開發工具可以用。
    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年12月16日 下午 03:20
  • 補充:

    Const WM_KEYDOWN = &H100
    Const WM_KEYUP = &H101
    Const WM_CLOSE = &H10
    Const VK_RETURN = &HD

     

    這些值都是以 "&H" 開頭 , 但表上是以00x000 那些表示 ,那是怎樣轉換的?

    把&H開頭,然後接上尾3碼?

    2010年12月17日 上午 03:48
  • http://zh.wikipedia.org/zh-tw/%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6

    把0x改成&H即可,C語言和VB的十六進制表示差異...


    2010年12月17日 上午 04:24
  • HI~各位~補充發問:

    Dim WinTitle As String = "未命名 - 記事本"
    Dim hWnd As Long = FindWindow(vbNullString, WinTitle) '由標題取得視窗的hWnd


    是由 標題取得視窗的hWnd,但如果那種標題有3個一樣的(包括後台的程式名都一樣)(例如叫XXX.exe),如果我指定要第2個的話,要怎樣寫?

    或者有另外的方法?

    2010年12月28日 上午 10:52
  • 用 EnumWindow 把你要的視窗全數過濾抓出來。
    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2010年12月28日 下午 04:30
  •   'API
        Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
         ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
        Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
         ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
        Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _
         ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long


        '常數
        Const WM_KEYDOWN = &H100
        Const WM_KEYUP = &H101
        Const WM_CLOSE = &H10
        Const VK_RETURN = &HD

        '宣告
        Dim WinTitle As String = "XXX"
        Dim hWnd As Long = FindWindow(vbNullString, WinTitle) '由標題取得視窗的hWnd

        '測試一:關閉視窗.可正常執行
        'SendMessage(hWnd, WM_CLOSE, 0, 0)
       
        '測試二:送出Enter鍵.無任何反應
    SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0)

        '測試三:改用PostMessage,送出Enter鍵.發生Error(Error內容如註1)
        PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0)

     

    這是大大給的提示,請問要怎樣解決postmessage的錯誤?

    對 PInvoke 函式 'WindowsApplication2!WindowsApplication2.MAKI::PostMessage' 的呼叫已使堆疊失去平衡。這可能是因為 Managed PInvoke 簽章和 Unmanaged 目標簽章不相符。請確認 PInvoke 簽章的呼叫慣例及參數與目標 Unmanaged 簽章是否相符。

    2010年12月29日 上午 03:21
  • SendMessage / PostMessage 除了名稱不一樣外,宣告完全相同,兩個只差在 SendMessage 送出後,會等對方回應後才返回,PostMessage 是送出後就不理了。

    所以你自己可以比對你上面錯在哪。

    另外 VB6 跟 VBNET 對 DLL 宣告差異非常大,不要隨便複製 VB6 的宣告,你那 PostMessage 宣告一看就知道是從 VB6 的程式碼複製來的。

     


    T.L. Cheng
    2011年1月1日 上午 06:37
    版主