问题描述
我想从我的应用程序调整大小和/或移动一些外部窗口,主要是屏幕键盘窗口.这是代码:
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();
}
但是问题是正确找到了IntPtr句柄,但是窗口既不移动也不调整大小.我尝试了机器人MoveWindow和SetWindowPos函数,但它们不起作用.
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()
函数有时返回代码
1400 (wrong hanlde),
有时
5 (Access denied).
我该如何解决?
推荐答案
屏幕键盘以很高的完整性级别运行.这意味着您还需要使流程在该完整性级别上运行.首先要做的是以管理员身份执行程序.这将以较高的完整性级别运行您的流程.
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.
当然,您不太可能发现提升您的应用程序的前景,因此向其用户展示UAC对话框非常吸引人.但这仅仅是系统设计的结果.
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.
请注意您的错误处理不正确.如果API函数失败,则仅检查错误代码.这意味着检查函数的返回值.而且您对SetWindowPos
的p/调用有缺陷.无法设置SetLastError
.这些细节确实很重要,您必须格外小心.编译器无法检查互操作代码的正确性.
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.
这篇关于WinAPI MoveWindow函数不适用于某些Windows的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!