标题: [问题求助] 如何让PowerShell创建的窗口居中显示在已打开的某窗口中央 [打印本页]
作者: 小白龙 时间: 2022-11-24 20:07 标题: 如何让PowerShell创建的窗口居中显示在已打开的某窗口中央
下面的代码可以在屏幕中央显示一个窗口, 我想让窗口显示在已打开的记事本窗口中央, 如果没有记事本窗口才显示在屏幕中央, 还没搜索到相关的资料- Add-Type -AssemblyName system.Windows.Forms
- Add-Type -AssemblyName system.Drawing
- $Form = New-Object windows.Forms.Form
- $Form.Size = New-Object drawing.Size(200, 120)
-
- $Form.startposition = "centerscreen"
- $Form.Text = "Test of Form"
- $Form.MaximizeBox = $false
- $Form.MinimizeBox = $false
- $Form.Font = New-Object drawing.Font("Times New Roman", 10, [Drawing.FontStyle]::Bold)
-
- $Form.BackColor = "LightBlue"
- $Form.FormBorderStyle = "FixedSingle"
- $Form.ShowDialog()
复制代码
作者: went 时间: 2022-11-24 21:51
用winapi- cls
- #Windows API
- $code=@'
- using System.Runtime.InteropServices;
- public static class WinApi{
- public struct Rect {
- public uint left;
- public uint top;
- public uint right;
- public uint bottom;
- };
- [DllImport("user32.dll")]
- public static extern bool SetWindowPos(uint hwnd,uint hpart,uint x,uint y,uint cx,uint cy,uint flags);
- [DllImport("user32.dll")]
- public static extern bool GetWindowRect(uint hwnd,ref Rect rect);
- }
- '@
- Add-Type -TypeDefinition $code
- Add-Type -AssemblyName system.Windows.Forms
- Add-Type -AssemblyName system.Drawing
-
-
- $Form = New-Object windows.Forms.Form
- $Form.Size = New-Object drawing.Size(200, 120)
-
- $Form.Text = "Test of Form"
- $Form.MaximizeBox = $false
- $Form.MinimizeBox = $false
- $Form.Font = New-Object drawing.Font("Times New Roman", 10, [Drawing.FontStyle]::Bold)
-
- $Form.BackColor = "LightBlue"
- $Form.FormBorderStyle = "FixedSingle"
-
- $rect = New-Object 'WinApi+Rect'
- $hwnd = (Get-Process notepad -ErrorAction SilentlyContinue| Select-Object -First 1).MainWindowHandle
- if($hwnd -eq $null){
- $Form.StartPosition = 'CenterScreen'
- } else {
- [void][WinApi]::GetWindowRect([int32]$hwnd,[ref]$rect)
- $x = $rect.left + ($rect.right - $rect.left - $Form.Width)/2
- $y = $rect.top + ($rect.bottom - $rect.top - $Form.Height)/2
- [WinApi]::SetWindowPos([int32]$Form.Handle,$null,$x,$y,0,0,1)
- }
-
- $Form.ShowDialog()
复制代码
作者: 小白龙 时间: 2022-11-25 08:40
回复 2# went
多谢大佬,
有两个问题请教:
1. 在我理解New-Object后应该跟着已经存在的类名, 但没有这个类
$rect = New-Object 'WinApi+Rect'
2.如果记事本窗口处于最小化时, 执行代码, 也会有响应, 但是只在任务栏上显示一个按钮, 点它也没反应,
能否加个判断, 如果有记事本程序运行着, 先激活它一下变成当前窗口,然后再执行代码?
作者: went 时间: 2022-11-25 10:43
本帖最后由 went 于 2022-11-25 10:48 编辑
回复 3# 小白龙
Rect是自定义的结构体
不想用结构体也可以直接传数组参数- cls
- #Windows API
- $code=@'
- using System.Runtime.InteropServices;
- public static class WinApi{
- [DllImport("user32.dll")]
- public static extern bool SetWindowPos(uint hwnd,uint hpart,uint x,uint y,uint cx,uint cy,uint flags);
- [DllImport("user32.dll")]
- public static extern bool GetWindowRect(uint hwnd,uint[] arr);
- [DllImport("user32.dll")]
- public static extern bool ShowWindow(uint hwnd,uint show);
- }
- '@
- Add-Type -TypeDefinition $code
- Add-Type -AssemblyName system.Windows.Forms
- Add-Type -AssemblyName system.Drawing
-
-
- $Form = New-Object windows.Forms.Form
- $Form.Size = New-Object drawing.Size(200, 120)
-
- $Form.Text = "Test of Form"
- $Form.MaximizeBox = $false
- $Form.MinimizeBox = $false
- $Form.Font = New-Object drawing.Font("Times New Roman", 10, [Drawing.FontStyle]::Bold)
-
- $Form.BackColor = "LightBlue"
- $Form.FormBorderStyle = "FixedSingle"
-
- $hwnd = (Get-Process notepad -ErrorAction SilentlyContinue| Select-Object -First 1).MainWindowHandle
- if($hwnd -eq $null){
- $Form.StartPosition = 'CenterScreen'
- } else {
- $arr = New-Object 'int32[]'(4)
- [void][WinApi]::ShowWindow([int32]$hwnd,1)
- [void][WinApi]::GetWindowRect([int32]$hwnd,$arr)
- $x = $arr[0] + ($arr[2] - $arr[0] - $Form.Width)/2
- $y = $arr[1] + ($arr[3] - $arr[1] - $Form.Height)/2
- [void][WinApi]::SetWindowPos([int32]$Form.Handle,$null,$x,$y,0,0,1)
- }
-
- $Form.ShowDialog()
复制代码
作者: 小白龙 时间: 2022-11-25 12:45
本帖最后由 小白龙 于 2022-11-25 13:08 编辑
回复 4# went
大佬技术666
我对C#不太懂, 但看起来还是前面的相对好理解一些,
另外, 请教大佬:
自定义的结构体,在新建其对象时, 必须要下面这种 类名+结构名 格式吗必须要+加号? 我改其它的名字都报错
'WinApi+Rect'
作者: went 时间: 2022-11-25 20:12
我是按tab自动补全出来的
试了下内部类和结构,在Powershell里都要用 [外部类名+内部类名]来表示- $code=@'
- public static class A{
- public static class A1 {}
- }
- public static class B{
- public struct B1 {}
- public class B2{}
- }
- public class C{
- public class C1{}
- }
- public struct D{}
- '@
- Add-Type -TypeDefinition $code
-
- #A & A+A1 & B 为静态类不能实例化对象
- New-Object 'B+B1'
- New-Object 'B+B2'
- New-Object 'C'
- New-Object 'C+C1'
- New-Object 'D'
复制代码
作者: 小白龙 时间: 2022-11-26 06:09
回复 6# went
非常感谢大佬详细解释,
我一直以为一个类里只能包含方法, 属性, 您上面的代码中, 类里又嵌套了各种类, 还包含了结构, 实在太复杂了,
下面是#2楼的第42行代码, 我把$null改成0也能运行, 我看后面也有两个0 这里用$null有什么含义吗
[WinApi]::SetWindowPos($Form.Handle, $null, $x, $y, 0, 0, 1)
[WinApi]::SetWindowPos($Form.Handle, 0, $x, $y, 0, 0, 1)
作者: went 时间: 2022-11-26 07:29
$null即0,只是类型不同,前者为指针,后者为数字,在winapi里面没有区别
作者: 小白龙 时间: 2022-11-29 16:53
回复 8# went
多谢大佬指教
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |