# 1.創建Yarp項目 目的:通過代理解決網路無法訪問openAI的問題 項目源碼地址:[https://github.com/raokun/YarpProject](https://github.com/raokun/YarpProject) ## 1.創建.net7 webapi項目 創建一個 ...
根據視窗句柄,移動/激活視窗
1.獲取視窗句柄
獲取視窗句柄上篇隨筆有寫,不再做贅述
2.引入User32函數MoveWindow/ShowWindow
引入MoveWindow,用於移動視窗,設置 SetLastError = true,若移動視窗失敗,方便查找問題
/// <summary> /// 設置目標窗體大小,位置 /// </summary> /// <param name="hWnd">目標句柄</param> /// <param name="x">目標窗體新位置X軸坐標</param> /// <param name="y">目標窗體新位置Y軸坐標</param> /// <param name="nWidth">目標窗體新寬度</param> /// <param name="nHeight">目標窗體新高度</param> /// <param name="BRePaint">是否刷新窗體</param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool BRePaint);
引入ShowWindow,用於激活視窗
/// <summary> /// 顯示Window /// </summary> /// <param name="hwnd">句柄</param> /// <param name="nCmdShow"> /// 0 隱藏視窗並激活另一個視窗。 /// 1 激活並顯示視窗。 如果視窗最小化或最大化,系統會將其還原到其原始大小和位置。 首次顯示視窗時,應用程式應指定此標誌。 /// 2 激活視窗並將其顯示為最小化視窗。 /// 3 激活視窗並顯示最大化的視窗。 /// 4 在其最近的大小和位置顯示一個視窗。 此值類似於 SW_SHOWNORMAL,但視窗未激活。 /// 5 激活視窗並以當前大小和位置顯示視窗。 /// 6 最小化指定的視窗,並按 Z 順序激活下一個頂級視窗。 /// 7 將視窗顯示為最小化視窗。 此值類似於 SW_SHOWMINIMIZED,但視窗未激活。 /// 8 以當前大小和位置顯示視窗。 此值類似於 SW_SHOW,但視窗未激活。 /// 9 激活並顯示視窗。 如果視窗最小化或最大化,系統會將其還原到其原始大小和位置。 還原最小化視窗時,應用程式應指定此標誌。 /// 10 根據啟動應用程式的程式傳遞給 CreateProcess 函數的 STARTUPINFO 結構中指定的SW_值設置顯示狀態。 /// 11 即使擁有視窗的線程未響應,也會最小化視窗。 僅當將視窗從不同的線程最小化時,才應使用此標誌。 /// </param> /// <returns></returns> [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
3.移動並激活視窗的一些細節
移動並激活視窗後,可能會因為一些原因,導致視窗移動了,也激活了,但被疊在其他視窗下麵。
預設兩種方案:
1).遍歷所有視窗,並用ShowWindow隱藏
2).模擬按下Win + M 最小化所有視窗,再激活需要調整的視窗
這裡只對第二種方案做示例:
1).引入User32函數keybd_event
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); /// <summary> /// /// </summary> /// <param name="bVk">虛擬鍵值</param> /// <param name="bScan">0</param> /// <param name="dwFlags">按下0,釋放2</param> /// <param name="dwExtraInfo">0</param> [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "keybd_event")] public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
2).模擬按鍵
keybd_event(0x5B, 0, 0, 0); keybd_event(77, 0, 0, 0); keybd_event(0x5B, 0, 0x02, 0); keybd_event(77, 0, 0x02, 0);
//0x5B == Win鍵
//77 == M鍵
4.示例:將兩個視窗在屏幕上併排顯示,實現分屏效果
var width = Screen.PrimaryScreen.WorkingArea.Width / 2; var height = Screen.PrimaryScreen.WorkingArea.Height; keybd_event(0x5B, 0, 0, 0); keybd_event(77, 0, 0, 0); keybd_event(0x5B, 0, 0x02, 0); keybd_event(77, 0, 0x02, 0); Task.Run(() => { Task.Delay(500).Wait(); ShowWindow(WindowsHandle1, 1); MoveWindow(WindowsHandle1, 0, 0, width, height, true); ShowWindow(WindowsHandle2, 1); MoveWindow(WindowsHandle2, width, 0, width, height, true); });
5.獲取MoveWindow的LastError
//上方調用MoveWindow int i = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
- 系統錯誤代碼 (0-499) (0x0-0x1f3)
- 系統錯誤代碼 (500-999) (0x1f4-0x3e7)
- 系統錯誤代碼 (1000-1299) (0x3e8-0x513)
- 系統錯誤代碼 (1300-1699) (0x514-0x6a3)
- 系統錯誤代碼 (1700-3999) (0x6a4-0xf9f)
- 系統錯誤代碼 (4000-5999) (0xfa0-0x176f)
- 系統錯誤代碼 (6000-8199) (0x1770-0x2007)
- 系統錯誤代碼 (8200-8999) (0x2008-0x2327)
- 系統錯誤代碼 (9000-11999) (0x2328-0x2edf)
- 系統錯誤代碼 (12000-15999) (0x2ee0-0x3e7f)