【问题标题】:Powershell: Sync Scrolling of two RichtextboxesPowershell:两个富文本框的同步滚动
【发布时间】:2018-08-10 22:34:01
【问题描述】:

我想同步两个Winforms Richtextboxes 的滚动。当 RTB2 被 scolled 时,RTB1 需要一直精确对齐。 我试图在这里转换这个 c#-Code LINK (second answer),但到目前为止失败了。所以我需要帮助。 现在它会产生多个错误:

Type [ScrollBarCommands] was not found...
Type [ScrollBarType] was not found....
Type [Message] was not found...
Also "illegal conversions" and so on.

这是一个示例脚本:

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object system.Windows.Forms.Form
$form.size  = "400,400"
$rtb1 = New-Object system.Windows.Forms.RichTextBox
$rtb1.size  = "190,350"
$rtb1.location = "200,1"
$rtb1.text = (1..300 | out-string)
$form.controls.add($rtb1)
$rtb2 = New-Object system.Windows.Forms.RichTextBox
$rtb2.size  = "190,350"
$rtb2.location = "1,1"
$rtb2.text = (1..300 | out-string)
$rtb2.scrollbars = "none"
$form.controls.add($rtb2)

$code = @'
public enum ScrollBarType : uint {
   SbHorz = 0,
   SbVert = 1,
   SbCtl = 2,
   SbBoth = 3
 }
public enum Message : uint {
   WM_VSCROLL = 0x0115
}
public enum ScrollBarCommands : uint {
   SB_THUMBPOSITION = 4
}
[DllImport( "User32.dll" )]
public extern static int GetScrollPos( IntPtr hWnd, int nBar );
[DllImport( "User32.dll" )]
public extern static int SendMessage( IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam );
'@
Add-Type -Name WinUtils -MemberDefinition $code -Namespace User32

$rtb1.add_VScroll({ 
   [uint32]$nPos = [User32.WinUtils]::GetScrollPos( $rtb1.Handle, [ScrollBarType]::SbVert )
   [uint32]$npos = $nPos -shl 16
   [uint32]$wParam = [ScrollBarCommands]::SB_THUMBPOSITION -bor $nPos
   [User32.WinUtils]::SendMessage( $rtb2.Handle, [Message]::WM_VSCROLL, $wParam , [ref]0)
})

$form.showdialog()

编者,请注意:不是重复的,这是关于**Powershell的。 :)**

【问题讨论】:

    标签: c# winforms powershell event-handling richtextbox


    【解决方案1】:

    ScrollBarTypeScrollBarCommandsMessageUser32.WinUtils 命名空间的成员。另外,ptr 应该是System.IntPtr

    编辑: 要在拖动滚动条时滚动$rtb2(而不仅仅是在释放鼠标时),您必须使用GetScrollInfo

    编辑 2: 固定箭头滚动按钮不起作用

    编辑 3: 修复了其他错误。重构代码。

    $typeDef = @"
    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    public enum ScrollBarType : uint {
        SbHorz = 0,
        SbVert = 1,
        SbCtl  = 2,
        SbBoth = 3
    }
    
    public enum Message : uint {
        WmVScroll = 0x0115
    }
    
    public enum ScrollBarCommands : uint {
        ThumbPosition = 4,
        ThumbTrack    = 5
    }
    
    [Flags()]
    public enum ScrollBarInfo : uint {
        Range           = 0x0001,
        Page            = 0x0002,
        Pos             = 0x0004,
        DisableNoScroll = 0x0008,
        TrackPos        = 0x0010,
    
        All = ( Range | Page | Pos | TrackPos )
    }
    
    public class CustomRichTextBox : RichTextBox {
        public Control Buddy { get; set; }
    
        public bool ThumbTrack = false;
    
        [StructLayout( LayoutKind.Sequential )]
        public struct ScrollInfo {
            public uint cbSize;
            public uint fMask;
            public int nMin;
            public int nMax;
            public uint nPage;
            public int nPos;
            public int nTrackPos;
        };
    
        [DllImport( "User32.dll" )]
        public extern static int SendMessage( IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam );
        [DllImport( "User32.dll" )]
        public extern static int GetScrollInfo( IntPtr hWnd, int fnBar, ref ScrollInfo lpsi );
    
        public void CustomVScroll() {
            int nPos;
    
            ScrollInfo scrollInfo = new ScrollInfo();
            scrollInfo.cbSize = (uint)Marshal.SizeOf( scrollInfo );
    
            if (ThumbTrack) {
                scrollInfo.fMask = (uint)ScrollBarInfo.TrackPos;
                GetScrollInfo( this.Handle, (int)ScrollBarType.SbVert, ref scrollInfo );
                nPos = scrollInfo.nTrackPos;
            } else {
                scrollInfo.fMask = (uint)ScrollBarInfo.Pos;
                GetScrollInfo( this.Handle, (int)ScrollBarType.SbVert, ref scrollInfo );
                nPos = scrollInfo.nPos;
            }
    
            nPos <<= 16;
            uint wParam = (uint)ScrollBarCommands.ThumbPosition | (uint)nPos;
            SendMessage( Buddy.Handle, (int)Message.WmVScroll, new IntPtr( wParam ), new IntPtr( 0 ) );
        }
    
        protected override void WndProc( ref System.Windows.Forms.Message m ) {
            if ( m.Msg == (int)Message.WmVScroll ) {
                if ( ( m.WParam.ToInt32() & 0xFF ) == (int)ScrollBarCommands.ThumbTrack ) {
                    ThumbTrack = true;
                } else {
                    ThumbTrack = false;
                }
            }
    
            base.WndProc( ref m );
        }
    }
    "@
    
    $assemblies = ("System.Windows.Forms", "System.Runtime.InteropServices")
    
    Add-Type -ReferencedAssemblies $assemblies -TypeDefinition $typeDef -Language CSharp
    
    ### Form
    
    $form = New-Object System.Windows.Forms.Form
    $form.Size = "400,400"
    
    ### Rich text box 1 (Synchronized - master)
    
    $rtb1 = New-Object CustomRichTextBox
    
    $rtb1.Size = "190,350"
    $rtb1.Location = "200,1"
    $rtb1.Text = (1..300 | Out-String)
    
    $form.Controls.Add($rtb1)
    
    ### Rich text box 2 (Synchronized - slave)
    
    $rtb2 = New-Object system.Windows.Forms.RichTextBox
    
    $rtb2.Size = "190,350"
    $rtb2.Location = "1,1"
    $rtb2.Text = (1..300 | Out-String)
    $rtb2.ScrollBars = "none"
    
    $form.Controls.Add($rtb2)
    
    ### Synchronization setup
    
    $rtb1.Buddy = $rtb2
    
    $rtb1.Add_VScroll({
        $this.CustomVScroll()
    })
    
    ### Run
    
    $form.ShowDialog()
    

    【讨论】:

    • 非常感谢!,还有一个问题:现在 RTB1 仅在用户完成滚动(释放鼠标按钮)时才会被滚动,有没有办法调整它以便 RTB1 在滚动时滚动用户还在滚动?
    • 不确定您的意思?
    • 试试吧,你就会明白我的意思了:) 当你滚动右边的盒子时,左边的盒子只有在你释放滚动条并停止滚动时才会滚动。这很好,但理想情况下两者会同时滚动。我刚刚看到:只有当您使用鼠标和滚动条时才会出现这种情况。
    • 哦,我没有注意到,因为我使用的是滚轮,它工作正常。让我看看我是否也能做到这一点..
    • 由于某种原因,[User32.WinUtils]::GetScrollPos( $rtb1.Handle, [User32.WinUtils+ScrollBarType]::SbVert ) 在拖动滚动条时没有更新。
    猜你喜欢
    • 2012-05-03
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 2015-11-09
    相关资源
    最近更新 更多