简体   繁体   English

使用自定义镶边强制调整透明WPF窗口的大小

[英]Force resize of transparent WPF window with custom chrome

I have been searching for hours and haven't found anything useful because all other issues are too localized, so here is my version of this (common) problem: 我一直在搜索几个小时,但没有找到任何有用的东西,因为所有其他问题都过于本地化,所以这是我的这个(常见)问题的版本:

I have a WPF window with WindowStyle=None and ResizeMode=NoResize (otherwise I would get resize borders which I do not want) and most important AllowsTransparency= False and I must stick to this setup. 我有一个WPF窗口, WindowStyle = NoneResizeMode = NoResize (否则我会得到我不想要的调整边框),最重要的是AllowTransparency = False ,我必须坚持这个设置。

Changing the ResizeMode to CanResize and having a custom resize grip with the following MouseDown handler 更改ResizeModeCanResize并具有自定义调整大小握以下的MouseDown处理程序

[DllImport("User32.dll")]
public static extern bool ReleaseCapture();

[DllImport("User32.dll")]
public static extern IntPtr SendMessage(
     IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);

private void OnResizeGripMouseDown(object sender, MouseButtonEventArgs e) {
    ReleaseCapture();
    SendMessage(Window.Handle, WM_NCLBUTTONDOWN, HTBOTTOMRIGHT, 0);
}

allows me to resize the window perfectly, however there is the resize border left. 允许我完美地调整窗口大小,但是剩下调整大小的边框。 Is there any way to force the resizability of the window although it has ResizeMode=NoResize ? 有没有办法强制窗口的可恢复性,虽然它有ResizeMode = NoResize

(Maybe via SetWindowLong and GWL_EXSTYLE ? If there is the the need for messages, I already have a WindowProc setup to handle this.) (也许通过SetWindowLongGWL_EXSTYLE ?如果需要消息,我已经有了一个WindowProc设置来处理这个。)

I was able to force the desired behaviour by using another message 我能够通过使用另一条消息强制执行所需的行为

SendMessage(Handle, WM_SYSCOMMAND, SC_SIZE + direction, 0);

where WM_SYSCOMMAND is the default Windows message, SC_SIZE is the wParam defined by 0xF000 and the direction is the numerical value of the hit test handle defined by this enum 其中WM_SYSCOMMAND是默认的Windows消息,SC_SIZE是由0xF000定义的wParam,方向是由此枚举定义的命中测试句柄的数值

public enum SysCommandSize : int {
     SC_SIZE_HTLEFT = 1,
     SC_SIZE_HTRIGHT = 2,
     SC_SIZE_HTTOP = 3,
     SC_SIZE_HTTOPLEFT = 4,
     SC_SIZE_HTTOPRIGHT = 5,
     SC_SIZE_HTBOTTOM = 6,
     SC_SIZE_HTBOTTOMLEFT = 7,
     SC_SIZE_HTBOTTOMRIGHT = 8
}

Christian, your solution brought me on the right way but it's lacking copy paste code for the dumb and lazy like me! 克里斯蒂安,你的解决方案带给我正确的方式,但它缺乏像我这样愚蠢和懒惰的复制粘贴代码! Here we go, if you uncomment the commented parts you can move the window around except for the borders. 在这里,如果您取消注释注释部分,您可以移动窗口,除了边框。

    private void Action_LMouseDownAndMove(object sender, MouseEventArgs e)
    {
        Point mousePosition = this.PointToClient(System.Windows.Forms.Cursor.Position);
        const int WM_NCLBUTTONDOWN = 0xA1;
        //const int HT_CAPTION = 0x2;
        if (e.Button == MouseButtons.Left)
        {
            ReleaseCapture();
            if (mousePosition.X < 20)
            {
                if (mousePosition.Y < 20)
                    SendMessage(Handle, WM_NCLBUTTONDOWN, 13, 0);
                else if (mousePosition.Y > this.Size.Height - 20)
                    SendMessage(Handle, WM_NCLBUTTONDOWN, 16, 0);
                else
                    SendMessage(Handle, WM_NCLBUTTONDOWN, 10, 0);
            }
            else if (mousePosition.X > this.Size.Width - 20)
            {
                if (mousePosition.Y < 20)
                    SendMessage(Handle, WM_NCLBUTTONDOWN, 14, 0);
                else if (mousePosition.Y > this.Size.Height - 20)
                    SendMessage(Handle, WM_NCLBUTTONDOWN, 17, 0);
                else
                    SendMessage(Handle, WM_NCLBUTTONDOWN, 11, 0);
            }
            else if (mousePosition.Y < 20)
                SendMessage(Handle, WM_NCLBUTTONDOWN, 12, 0);
            else if (mousePosition.Y > this.Size.Height - 20)
                SendMessage(Handle, WM_NCLBUTTONDOWN, 15, 0);
            //else
            //  SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        }

Change the 20 pixel value depending on your taste. 根据您的喜好更改20像素值。 I am not 100% sure left/right and top/bottom have exactly the same resize areas or whether one value needs to be 19/21 if you know what I mean... There are some reduction possibilities for the if/else tree here, I know. 我不是100%确定左/右和上/下具有完全相同的调整大小区域,或者如果你知道我的意思,一个值是否需要是19/21 ...这里有if / else树的一些减少可能性, 我知道。 And instead of 20 I should use a constant. 而不是20我应该使用常数。

To change the cursor for showing the user he can resize I use the following code, it's simply a MouseMove Event handler: 要更改用于显示用户的光标,他可以调整大小,我使用以下代码,它只是一个MouseMove事件处理程序:

        this.pictureBox.MouseMove += new MouseEventHandler((a, e) =>
        {
            Point h = this.PointToClient(System.Windows.Forms.Cursor.Position);

            if (h.X < 20)
            {
                if (h.Y < 20)
                {
                    pictureBox.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
                }
                else if (h.Y > this.Size.Height - 20)
                {
                    pictureBox.Cursor = System.Windows.Forms.Cursors.SizeNESW;
                }
                else
                {
                    pictureBox.Cursor = System.Windows.Forms.Cursors.SizeWE;
                }
            }
            else if (h.X > this.Size.Width - 20)
            {
                if (h.Y < 20)
                {
                    pictureBox.Cursor = System.Windows.Forms.Cursors.SizeNESW;
                }
                else if (h.Y > this.Size.Height - 20)
                {
                    pictureBox.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
                }
                else
                {
                    pictureBox.Cursor = System.Windows.Forms.Cursors.SizeWE;
                }
            }
            else if (h.Y < 20)
            {
                pictureBox.Cursor = System.Windows.Forms.Cursors.SizeNS;
            }
            else if (h.Y > this.Size.Height - 20)
            {
                pictureBox.Cursor = System.Windows.Forms.Cursors.SizeNS;
            }
            else
            {
                pictureBox.Cursor = System.Windows.Forms.Cursors.Default;
            }
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM