问题
I want to resize and/or move some external windows from my application, mainly the On-Screen keyboardwindow. Here is the code:
[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();
}
But the problem is that the IntPtr handle is found correctly, but the window is neither moved nor resized. I tried bot MoveWindow and SetWindowPos functions, and they does not work.
GetLastWin32Error()
function returns sometimes code
1400 (wrong hanlde),
sometimes
5 (Access denied).
How can I solve that?
回答1:
The on screen keyboard runs at a high integrity level. This means that you need your process also to run at that integrity level. The first thing to do is to execute your program as admin. That will run your process at a high integrity level.
Of course, you are unlikely to find the prospect of running your app elevated, and so presenting its users with UAC dialogs, very appealing. But that's just a consequence of the system design.
Do note that your error handling is incorrect. Only check the error code if the API functions fails. Which means checking the return value of the function. And your p/invoke for SetWindowPos
is flawed. It fails to set SetLastError
. These details really do matter and you must take great care. The compiler cannot check interop code for correctness.
来源:https://stackoverflow.com/questions/24796509/winapi-movewindow-function-not-working-for-some-windows