2014-07-17 64 views
1

我想调整大小和/或从我的应用程序中移动一些外部窗口,主要是屏幕上的键盘窗口。下面是代码:WinAPI MoveWindow函数不适用于某些窗口

 [DllImport("user32.dll", SetLastError = true)] 
    internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); 

    [DllImport("user32.dll", EntryPoint = "SetWindowPos")] 
    public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags); 


    //assorted constants needed 
    public static uint MF_BYPOSITION = 0x400; 
    public static uint MF_REMOVE = 0x1000; 
    public static int GWL_STYLE = -16; 
    public static int WS_CHILD = 0x40000000; //child window 
    public static int WS_BORDER = 0x00800000; //window with border 
    public static int WS_DLGFRAME = 0x00400000; //window with double border but no title 
    public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar 
    public static int WS_SYSMENU = 0x00080000; //window menu 

    public const byte KEYEVENTF_EXTENDEDKEY = 0x0001; //Key down flag 
    public const byte KEYEVENTF_KEYUP = 0x0002; //Key up flag 
    public const byte VK_RCONTROL = 0xA3; //Top Control key code 
    public const byte VK_CONTROL = 0x80; //Left Control key code 

    const short SWP_NOMOVE = 0X2; 
    const short SWP_NOSIZE = 1; 
    const short SWP_NOZORDER = 0X4; 
    const int SWP_SHOWWINDOW = 0x0040; 

    #endregion 

    public static void WindowsReStyle() 
    { 

     Process p = Process.GetProcesses().Where(d => d.ProcessName.Contains("osk")).DefaultIfEmpty(null).FirstOrDefault(); 

     IntPtr hWndOSK = p.MainWindowHandle; 

     string title = p != null ? p.MainWindowTitle : ""; 

     bool b = MoveWindow(hWndOSK, 600, 600, 600, 600, true); 

     int i = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); 

     SetWindowPos(hWndOSK, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); 

     i = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); 
    } 

但问题是,IntPtr的手柄被正确发现,但窗口既不移动也不调整。我尝试了Bot MoveWindow和SetWindowPos函数,但它们不起作用。

GetLastWin32Error() 

功能有时会返回码

1400 (wrong hanlde), 

有时

5 (Access denied). 

我怎样才能解决呢?

+0

我编辑了你的标题。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 –

+3

应用程序可以通过处理WM_WINDOWPOSCHANGING来抵制被调整大小的尝试。 – user1793036

回答

3

屏幕键盘运行在高完整性级别。这意味着您还需要您的流程以完整性级别运行。首先要做的是以管理员身份执行你的程序。这将以高完整性水平运行您的流程。

当然,您不太可能找到提升应用程序运行的前景,因此向用户展示UAC对话框非常有吸引力。但这只是系统设计的结果。

请注意您的错误处理不正确。如果API函数失败,只能检查错误代码。这意味着检查函数的返回值。你的p/invoke为SetWindowPos是有缺陷的。它未能设置SetLastError。这些细节确实很重要,你必须非常小心。编译器无法检查互操作代码的正确性。