|
When I saw that the article was 2004, I decided to look for another solution (I thought it would not work well on Windows 10), but those who had found bugs, it worked 100%, Thanks
|
|
|
|
|
Hi:
Thanks for making the auto scroll panel available. It works great. Can you let me the licensing for this component? I am using it in an in-house tool.
Thanks,
Steve
|
|
|
|
|
A panel with horizontal scrollbar is what bothered me so long.And your article helps me.
Thank you so much.
|
|
|
|
|
I was battling with the mousewheel messages on the panel, and couldn't figure it out. Your article helped me get it done. Good job!
|
|
|
|
|
I don't know why, but when I set the VisibleAutoScrollHorizontal to false, the horizontal scroll bar is still displayed. However, if I set the VisibleAutoScrollVertical to false, the vertical scroll bar is not displayed.
Any idea what might cause it?
|
|
|
|
|
I wanted to try to use this project to synchronize two autoscroll panels. I added another panel to the form named scrollabelPanel1. I wanted it to track the panel1 HScroll but ignore the Vertical scroll.
I changed the numericUpDown function for the H Pos Box to the following:
private void numericUpDown5_ValueChanged(object sender, System.EventArgs e)
{
this.panel1.AutoScrollHPos = System.Convert.ToInt32(
this.numericUpDown5.Value);
this.scrollablePanel1.AutoScrollHPos =
System.Convert.ToInt32( this.numericUpDown5.Value );
this.scrollablePanel1.performScrollHorizontal(
ScrollEventType.ThumbTrack);
}
It works great on my machine. My new panel tracks panel1 when panl1 is horizontally scrolled. However, if i send the project and the bin/.exe to another machine it doesn't work. Both Machines run dual displays, both run Windows XP SP2. Both machines are running the project from VS 2003. Is this possibly a windows setting? Graphics Card issue? Any ideas would be appreciated. Thank you.
-- modified at 12:22 Thursday 7th December, 2006
|
|
|
|
|
After reading the article here, "http://www.codeproject.com/listctrl/synchscroll.asp" I got an idea as to what was going on.
It seems that dragging the scrollbar thumb produced a series of SB_THUMBTRACK messages for each mousemove but would not update the contents until the mouse button was released and the END_SCROLL message was triggered. All of the other SB scroll types worked because they are are discrete, each produces one change in the position of the scrollbar thumb and then calls END_SCROLL and finally redraws the panel.
It turns out that Windows XP (eXtraProblems) Has a setting in the Display Properties >> Appearance >> Effects called "Show window contents while dragging" that seems to control whether or not the SB_THUMBTRACK message triggers a WM_ERASEBKGND, WM_PAINT event to occur.
As it turns out, if show window contents is set to true then
"msg=0x14 (WM_ERASEBKGND) hwnd=0x400a9a wparam=0x7b012c66 lparam=0x0 result=0x1
msg=0xf (WM_PAINT) hwnd=0x400a9a wparam=0x0 lparam=0x0 result=0x0"
is sent after each SB_THMBTRACK. If show window contents is set to false then the WM_ERASEBKGND and WM_PAINT are not called until the thumb is released and the END_SCROLL message is sent.
|
|
|
|
|
Hi there, I just tried out your app and added the following code to Form1's constructor:
<br />
for (int i = 0;i < 10; i++)<br />
{<br />
System.Windows.Forms.TextBox textBox = new System.Windows.Forms.TextBox();<br />
textBox.Dock = DockStyle.Top;<br />
panel2.Controls.Add(textBox);<br />
}<br />
And if I tab through the controls, your panel doesn't pick up on the scroll events.
Tim
|
|
|
|
|
What about always on scroll bars?
|
|
|
|
|
I have used your panel in two forms. While closing one form and opening the other form, an exception is generated by the wndproc and shuts down the application. Is there any way in which this can be handled. The exception is not generated always, but sometimes. Can I dispose off the panel cleanly before using it in another form?
|
|
|
|
|
super cool, just what i was looking for, thanks bro
para saaan naman ito
|
|
|
|
|
Any ideas why it is so and how to resolve?
Thanks
|
|
|
|
|
After I found this article, I was wondering if there might not be an easier way if you want to detect the movement of the scrollbar. It turns out that whenever you scroll the control, it apparently causes an OnPaint event for the control. I put some code in the Paint handler to get the AutoScrollPosition.
I'm using this approach to get one panel to track the vertical position of an adjacent panel (kind of like with MS Project), but I'm having trouble hiding the vertical scroll bar on the slave panel. I have the following code handling the OnLayout event for the slave panel:
private void panel1_Layout(object sender, System.Windows.Forms.LayoutEventArgs e)
{
ShowScrollBar(panel1.Handle, SB_VERT, false);
}
However, the scroll bar on panel1 keeps flashing on and off. Something keeps showing the scrollbar again I think. I don't need the ability to turn the vertical scrollbar on and off...I just want to hide it for good. But I do want to show the horizontal scrollbar. Any ideas?
I tried putting the above code into the Paint handler for the slave panel, and also in the Paint handler for the master (controlling) panel, but the scrollbar for the slave panel still flashes while I'm scrolling.
|
|
|
|
|
I noticed that if the vertical scroll bar is disabled, a move of the mouse wheel will still result in vertical movement. Is it possible to prevent the wheel from scrolling all together. I would like to use the wheel for zooming purposes an not scrolling at all!
|
|
|
|
|
Yeah, I'm interested in that too, I would like to use the mousewheel for zooming only but the panel scrolls at the same time.
|
|
|
|
|
1. Controlling scroll position using AutoScrollHPos and AutoScrollVPos moves the scrollbar in the panel correctly, but doesn't actually scroll the contents of the panel.
2. VisibleAutoHorizontal and VisibleAutoVertical had no effect on a panel - scrollbars were still visible.
I will email you the version containing my bug fixes. Thanks for your work on this!
|
|
|
|
|
Can you send me the bug fixes too?
cyrus at whozin dot com
Thanks!
----------------------------------------------------
I do believe in monsters, I call them officers....
|
|
|
|
|
Well, it seems that this component should have a patch because of the numerous bugs detected. I noticed that the VisibleAutoScrollVertical property has no effect, could you please (Manalee Software) update the post with the bugfix?
Or - meanwhile - anybody please send the fix to me via mail: dester31 [at] gmail [dot] com
Thanks: Dester
|
|
|
|
|
If any of the ScrollVertical, ScrollHorizontal, or ScrollMouseWheel events are not subscribed to, there can be a noticeable delay during the first scroll while windows is tries to figure out what to do with these events.
The solution is very simple. In the WndProc method, substitute the following code:
if (this.ScrollMouseWheel != null)
{
this.ScrollMouseWheel(this, arg0);
}
if (this.ScrollVertical != null)
{
this.ScrollVertical(this, arg);
}
if (this.ScrollHorizontal != null)
{
this.ScrollHorizontal(this, arg);
}
Great article. Thanks.
--Gary
|
|
|
|
|
//==================================
// Form1.h
//==================================
#pragma once
#include "ScrollablePanel.h"
namespace ScrollPanel
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
///
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
///
public __gc class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
}
protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super::Dispose(disposing);
}
private:
///
/// Required designer variable.
///
CustomAutoScrollPanel::ScrollablePanel * panel1;
System::Windows::Forms::Panel * panel2;
System::Windows::Forms::Button * button1;
System::Windows::Forms::Button * button2;
System::Windows::Forms::Label * label1;
System::Windows::Forms::CheckBox * checkBox1;
System::Windows::Forms::CheckBox * checkBox2;
System::Windows::Forms::Label * label2;
System::Windows::Forms::CheckBox * checkBox3;
System::Windows::Forms::CheckBox * checkBox4;
System::Windows::Forms::Button * button3;
System::Windows::Forms::Button * button4;
System::Windows::Forms::Label * label3;
System::Windows::Forms::Label * label4;
System::Windows::Forms::Button * button5;
System::Windows::Forms::Button * button6;
System::Windows::Forms::Button * button7;
System::Windows::Forms::Button * button8;
System::Windows::Forms::GroupBox * groupBox1;
System::Windows::Forms::Label * label5;
System::Windows::Forms::Label * label6;
System::Windows::Forms::Label * label7;
System::Windows::Forms::Label * label8;
System::Windows::Forms::NumericUpDown * numericUpDown1;
System::Windows::Forms::NumericUpDown * numericUpDown2;
System::Windows::Forms::NumericUpDown * numericUpDown3;
System::Windows::Forms::NumericUpDown * numericUpDown4;
System::Windows::Forms::Label * label9;
System::Windows::Forms::Label * label10;
System::Windows::Forms::NumericUpDown * numericUpDown5;
System::Windows::Forms::NumericUpDown * numericUpDown6;
System::Windows::Forms::Label * label11;
System::ComponentModel::Container * components;
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
void InitializeComponent(void)
{
this->components = new System::ComponentModel::Container();
this->panel1 = new CustomAutoScrollPanel::ScrollablePanel();
this->panel2 = new System::Windows::Forms::Panel();
this->label11 = new System::Windows::Forms::Label();
this->button1 = new System::Windows::Forms::Button();
this->button2 = new System::Windows::Forms::Button();
this->label1 = new System::Windows::Forms::Label();
this->checkBox1 = new System::Windows::Forms::CheckBox();
this->checkBox2 = new System::Windows::Forms::CheckBox();
this->label2 = new System::Windows::Forms::Label();
this->checkBox3 = new System::Windows::Forms::CheckBox();
this->checkBox4 = new System::Windows::Forms::CheckBox();
this->button3 = new System::Windows::Forms::Button();
this->button4 = new System::Windows::Forms::Button();
this->label3 = new System::Windows::Forms::Label();
this->label4 = new System::Windows::Forms::Label();
this->button5 = new System::Windows::Forms::Button();
this->button6 = new System::Windows::Forms::Button();
this->button7 = new System::Windows::Forms::Button();
this->button8 = new System::Windows::Forms::Button();
this->groupBox1 = new System::Windows::Forms::GroupBox();
this->numericUpDown4 = new System::Windows::Forms::NumericUpDown();
this->numericUpDown3 = new System::Windows::Forms::NumericUpDown();
this->numericUpDown2 = new System::Windows::Forms::NumericUpDown();
this->numericUpDown1 = new System::Windows::Forms::NumericUpDown();
this->label8 = new System::Windows::Forms::Label();
this->label7 = new System::Windows::Forms::Label();
this->label6 = new System::Windows::Forms::Label();
this->label5 = new System::Windows::Forms::Label();
this->label9 = new System::Windows::Forms::Label();
this->label10 = new System::Windows::Forms::Label();
this->numericUpDown5 = new System::Windows::Forms::NumericUpDown();
this->numericUpDown6 = new System::Windows::Forms::NumericUpDown();
this->panel1->SuspendLayout();
this->panel2->SuspendLayout();
this->groupBox1->SuspendLayout();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown4))->BeginInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown3))->BeginInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown2))->BeginInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown1))->BeginInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown5))->BeginInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown6))->BeginInit();
this->SuspendLayout();
//
// panel1
//
this->panel1->AutoScroll = true;
this->panel1->AutoScrollHorizontalMaximum = 100;
this->panel1->AutoScrollHorizontalMinimum = 0;
this->panel1->AutoScrollHPos = 0;
this->panel1->AutoScrollVerticalMaximum = 100;
this->panel1->AutoScrollVerticalMinimum = 0;
this->panel1->AutoScrollVPos = 0;
this->panel1->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;
this->panel1->Controls->Add(this->panel2);
this->panel1->EnableAutoScrollHorizontal = true;
this->panel1->EnableAutoScrollVertical = true;
this->panel1->Location = System::Drawing::Point(24, 80);
this->panel1->Name = "panel1";
this->panel1->Size = System::Drawing::Size(208, 176);
this->panel1->TabIndex = 0;
this->panel1->VisibleAutoScrollHorizontal = true;
this->panel1->VisibleAutoScrollVertical = true;
this->panel1->ScrollVertical += new System::Windows::Forms::ScrollEventHandler(this, panel1_ScrollVertical);
this->panel1->ScrollHorizontal += new System::Windows::Forms::ScrollEventHandler(this, panel1_ScrollHorizontal);
this->panel1->ScrollMouseWheel += new System::Windows::Forms::MouseEventHandler(this, panel1_ScrollMouseWheel);
//
// panel2
//
this->panel2->BackColor = System::Drawing::SystemColors::ActiveCaptionText;
this->panel2->Controls->Add(this->label11);
this->panel2->Location = System::Drawing::Point(20, 16);
this->panel2->Name = "panel2";
this->panel2->Size = System::Drawing::Size(248, 296);
this->panel2->TabIndex = 0;
this->panel2->Click += new System::EventHandler(this, panel2_Click);
//
// label11
//
this->label11->Location = System::Drawing::Point(24, 32);
this->label11->Name = "label11";
this->label11->Size = System::Drawing::Size(136, 86);
this->label11->TabIndex = 0;
this->label11->Text = "I\'m a big panel inside a panel with autoscroll=true. clic inside panel to use mou"
"sewheel 9056340568 506945- -569-m 905689045690 45906596804 456405 506045064056";
this->label11->Click += new System::EventHandler(this, label11_Click);
//
// button1
//
this->button1->Location = System::Drawing::Point(264, 96);
this->button1->Name = "button1";
this->button1->Size = System::Drawing::Size(112, 24);
this->button1->TabIndex = 1;
this->button1->Text = "Large VScroll up";
this->button1->Click += new System::EventHandler(this, button1_Click);
//
// button2
//
this->button2->Location = System::Drawing::Point(264, 128);
this->button2->Name = "button2";
this->button2->Size = System::Drawing::Size(112, 23);
this->button2->TabIndex = 2;
this->button2->Text = "Large VScroll down";
this->button2->Click += new System::EventHandler(this, button2_Click);
//
// label1
//
this->label1->Location = System::Drawing::Point(16, 272);
this->label1->Name = "label1";
this->label1->Size = System::Drawing::Size(96, 16);
this->label1->TabIndex = 3;
this->label1->Text = "Scroll events:";
//
// checkBox1
//
this->checkBox1->Checked = true;
this->checkBox1->CheckState = System::Windows::Forms::CheckState::Checked;
this->checkBox1->Location = System::Drawing::Point(8, 40);
this->checkBox1->Name = "checkBox1";
this->checkBox1->Size = System::Drawing::Size(152, 16);
this->checkBox1->TabIndex = 4;
this->checkBox1->Text = "Enable horizontal scroll";
this->checkBox1->CheckedChanged += new System::EventHandler(this, checkBox1_CheckedChanged);
//
// checkBox2
//
this->checkBox2->Checked = true;
this->checkBox2->CheckState = System::Windows::Forms::CheckState::Checked;
this->checkBox2->Location = System::Drawing::Point(192, 40);
this->checkBox2->Name = "checkBox2";
this->checkBox2->Size = System::Drawing::Size(136, 16);
this->checkBox2->TabIndex = 5;
this->checkBox2->Text = "Enable vertical scroll";
this->checkBox2->CheckedChanged += new System::EventHandler(this, checkBox2_CheckedChanged);
//
// label2
//
this->label2->ForeColor = System::Drawing::Color::OrangeRed;
this->label2->Location = System::Drawing::Point(112, 272);
this->label2->Name = "label2";
this->label2->Size = System::Drawing::Size(252, 16);
this->label2->TabIndex = 6;
//
// checkBox3
//
this->checkBox3->Checked = true;
this->checkBox3->CheckState = System::Windows::Forms::CheckState::Checked;
this->checkBox3->Location = System::Drawing::Point(8, 16);
this->checkBox3->Name = "checkBox3";
this->checkBox3->Size = System::Drawing::Size(160, 16);
this->checkBox3->TabIndex = 7;
this->checkBox3->Text = "Visible horizontal scroll";
this->checkBox3->CheckedChanged += new System::EventHandler(this, checkBox3_CheckedChanged);
//
// checkBox4
//
this->checkBox4->Checked = true;
this->checkBox4->CheckState = System::Windows::Forms::CheckState::Checked;
this->checkBox4->Location = System::Drawing::Point(192, 16);
this->checkBox4->Name = "checkBox4";
this->checkBox4->Size = System::Drawing::Size(136, 16);
this->checkBox4->TabIndex = 8;
this->checkBox4->Text = "Visible vertical scroll";
this->checkBox4->CheckedChanged += new System::EventHandler(this, checkBox4_CheckedChanged);
//
// button3
//
this->button3->Location = System::Drawing::Point(264, 184);
this->button3->Name = "button3";
this->button3->Size = System::Drawing::Size(112, 24);
this->button3->TabIndex = 9;
this->button3->Text = "Large HScroll right";
this->button3->Click += new System::EventHandler(this, button3_Click);
//
// button4
//
this->button4->Location = System::Drawing::Point(264, 216);
this->button4->Name = "button4";
this->button4->Size = System::Drawing::Size(112, 23);
this->button4->TabIndex = 10;
this->button4->Text = "Large HScroll left";
this->button4->Click += new System::EventHandler(this, button4_Click);
//
// label3
//
this->label3->Location = System::Drawing::Point(16, 296);
this->label3->Name = "label3";
this->label3->Size = System::Drawing::Size(112, 16);
this->label3->TabIndex = 11;
this->label3->Text = "Mousewheel events:";
//
// label4
//
this->label4->ForeColor = System::Drawing::Color::OrangeRed;
this->label4->Location = System::Drawing::Point(128, 296);
this->label4->Name = "label4";
this->label4->Size = System::Drawing::Size(216, 16);
this->label4->TabIndex = 12;
//
// button5
//
this->button5->Location = System::Drawing::Point(392, 96);
this->button5->Name = "button5";
this->button5->Size = System::Drawing::Size(112, 23);
this->button5->TabIndex = 13;
this->button5->Text = "Small VScroll up";
this->button5->Click += new System::EventHandler(this, button5_Click);
//
// button6
//
this->button6->Location = System::Drawing::Point(392, 128);
this->button6->Name = "button6";
this->button6->Size = System::Drawing::Size(112, 23);
this->button6->TabIndex = 14;
this->button6->Text = "Small VScroll down";
this->button6->Click += new System::EventHandler(this, button6_Click);
//
// button7
//
this->button7->Location = System::Drawing::Point(392, 184);
this->button7->Name = "button7";
this->button7->Size = System::Drawing::Size(112, 23);
this->button7->TabIndex = 15;
this->button7->Text = "Small HScroll right";
this->button7->Click += new System::EventHandler(this, button7_Click);
//
// button8
//
this->button8->Location = System::Drawing::Point(392, 216);
this->button8->Name = "button8";
this->button8->Size = System::Drawing::Size(112, 23);
this->button8->TabIndex = 16;
this->button8->Text = "Small HScroll left";
this->button8->Click += new System::EventHandler(this, button8_Click);
//
// groupBox1
//
this->groupBox1->Controls->Add(this->numericUpDown4);
this->groupBox1->Controls->Add(this->numericUpDown3);
this->groupBox1->Controls->Add(this->numericUpDown2);
this->groupBox1->Controls->Add(this->numericUpDown1);
this->groupBox1->Controls->Add(this->label8);
this->groupBox1->Controls->Add(this->label7);
this->groupBox1->Controls->Add(this->label6);
this->groupBox1->Controls->Add(this->label5);
this->groupBox1->Enabled = true;
this->groupBox1->FlatStyle = System::Windows::Forms::FlatStyle::System;
this->groupBox1->Location = System::Drawing::Point(336, 8);
this->groupBox1->Name = "groupBox1";
this->groupBox1->Size = System::Drawing::Size(160, 80);
this->groupBox1->TabIndex = 17;
this->groupBox1->TabStop = false;
this->groupBox1->Text = "Range";
//
// numericUpDown4
//
this->numericUpDown4->Location = System::Drawing::Point(104, 48);
this->numericUpDown4->Name = "numericUpDown4";
this->numericUpDown4->Size = System::Drawing::Size(40, 20);
this->numericUpDown4->TabIndex = 7;
this->numericUpDown4->Value = 0;
this->numericUpDown4->Maximum = 100;
this->numericUpDown4->Minimum = 0;
this->numericUpDown4->ValueChanged += new System::EventHandler(this, numericUpDown4_ValueChanged);
//
// numericUpDown3
//
this->numericUpDown3->Location = System::Drawing::Point(40, 48);
this->numericUpDown3->Name = "numericUpDown3";
this->numericUpDown3->Size = System::Drawing::Size(40, 20);
this->numericUpDown3->TabIndex = 6;
this->numericUpDown3->Value = 0;
this->numericUpDown3->Maximum = 100;
this->numericUpDown3->Minimum = 0;
this->numericUpDown3->ValueChanged += new System::EventHandler(this,numericUpDown3_ValueChanged);
//
// numericUpDown2
//
this->numericUpDown2->Location = System::Drawing::Point(104, 24);
this->numericUpDown2->Name = "numericUpDown2";
this->numericUpDown2->Size = System::Drawing::Size(40, 20);
this->numericUpDown2->TabIndex = 5;
this->numericUpDown2->Value = 0;
this->numericUpDown2->Maximum = 100;
this->numericUpDown2->Minimum = 0;
this->numericUpDown2->ValueChanged += new System::EventHandler(this,numericUpDown2_ValueChanged);
//
// numericUpDown1
//
this->numericUpDown1->Location = System::Drawing::Point(40, 24);
this->numericUpDown1->Name = "numericUpDown1";
this->numericUpDown1->Size = System::Drawing::Size(40, 20);
this->numericUpDown1->TabIndex = 4;
this->numericUpDown1->Value = 0;
this->numericUpDown1->Maximum = 100;
this->numericUpDown1->Minimum = 0;
this->numericUpDown1->ValueChanged += new System::EventHandler(this,numericUpDown1_ValueChanged);
//
// label8
//
this->label8->Location = System::Drawing::Point(104, 8);
this->label8->Name = "label8";
this->label8->Size = System::Drawing::Size(32, 16);
this->label8->TabIndex = 3;
this->label8->Text = "Max";
//
// label7
//
this->label7->Location = System::Drawing::Point(48, 8);
this->label7->Name = "label7";
this->label7->Size = System::Drawing::Size(32, 16);
this->label7->TabIndex = 2;
this->label7->Text = "Min";
//
// label6
//
this->label6->Location = System::Drawing::Point(16, 48);
this->label6->Name = "label6";
this->label6->Size = System::Drawing::Size(16, 16);
this->label6->TabIndex = 1;
this->label6->Text = "V";
//
// label5
//
this->label5->Location = System::Drawing::Point(16, 24);
this->label5->Name = "label5";
this->label5->Size = System::Drawing::Size(16, 16);
this->label5->TabIndex = 0;
this->label5->Text = "H";
//
// label9
//
this->label9->Location = System::Drawing::Point(392, 272);
this->label9->Name = "label9";
this->label9->Size = System::Drawing::Size(40, 16);
this->label9->TabIndex = 18;
this->label9->Text = "H Pos";
//
// label10
//
this->label10->Location = System::Drawing::Point(392, 296);
this->label10->Name = "label10";
this->label10->Size = System::Drawing::Size(40, 16);
this->label10->TabIndex = 19;
this->label10->Text = "V Pos";
//
// numericUpDown5
//
this->numericUpDown5->Location = System::Drawing::Point(440, 272);
this->numericUpDown5->Maximum = 10000;
this->numericUpDown5->Minimum = 0;
this->numericUpDown5->Name = "numericUpDown5";
this->numericUpDown5->Size = System::Drawing::Size(48, 20);
this->numericUpDown5->TabIndex = 20;
this->numericUpDown5->ValueChanged += new System::EventHandler(this,numericUpDown5_ValueChanged);
//
// numericUpDown6
//
this->numericUpDown6->Location = System::Drawing::Point(440, 296);
this->numericUpDown6->Maximum = 10000;
this->numericUpDown6->Minimum = 0;
this->numericUpDown6->Name = "numericUpDown6";
this->numericUpDown6->Size = System::Drawing::Size(48, 20);
this->numericUpDown6->TabIndex = 21;
this->numericUpDown6->ValueChanged += new System::EventHandler(this,numericUpDown6_ValueChanged);
//
// Form1
//
this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
this->ClientSize = System::Drawing::Size(528, 326);
this->Controls->Add(this->numericUpDown6);
this->Controls->Add(this->numericUpDown5);
this->Controls->Add(this->label10);
this->Controls->Add(this->label9);
this->Controls->Add(this->groupBox1);
this->Controls->Add(this->button8);
this->Controls->Add(this->button7);
this->Controls->Add(this->button6);
this->Controls->Add(this->button5);
this->Controls->Add(this->label4);
this->Controls->Add(this->label3);
this->Controls->Add(this->button4);
this->Controls->Add(this->button3);
this->Controls->Add(this->checkBox4);
this->Controls->Add(this->checkBox3);
this->Controls->Add(this->label2);
this->Controls->Add(this->checkBox2);
this->Controls->Add(this->checkBox1);
this->Controls->Add(this->label1);
this->Controls->Add(this->button2);
this->Controls->Add(this->button1);
this->Controls->Add(this->panel1);
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
this->Name = "Form1";
this->Text = "Customize AutoScroll Panel";
this->panel1->ResumeLayout(false);
this->panel2->ResumeLayout(false);
this->groupBox1->ResumeLayout(false);
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown4))->EndInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown3))->EndInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown2))->EndInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown1))->EndInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown5))->EndInit();
//((System::ComponentModel::ISupportInitialize)(this->numericUpDown6))->EndInit();
this->ResumeLayout(false);
}
private: void panel2_Click(Object * sender, System::EventArgs * e)
{
this->panel1->Focus();
}
private: void checkBox1_CheckedChanged(Object * sender, System::EventArgs * e)
{
this->panel1->EnableAutoScrollHorizontal = this->checkBox1->Checked;
}
private: void checkBox2_CheckedChanged(Object * sender, System::EventArgs * e)
{
this->panel1->EnableAutoScrollVertical = this->checkBox2->Checked;
}
private: void panel1_ScrollHorizontal(Object * sender, System::Windows::Forms::ScrollEventArgs * e)
{
String * msg = String::Concat(S"horizontal scroll :: type: " , __box(e->Type)->ToString());
this->label2->Text = msg;
this->numericUpDown5->Value = e->NewValue;
}
private: void panel1_ScrollVertical(Object * sender, System::Windows::Forms::ScrollEventArgs * e)
{
String * msg = String::Concat("vertical scroll :: type: ", __box(e->Type)->ToString() );
msg = String::Format("{0} :: pos : {1}", msg, __box(e->NewValue) );
this->label2->Text =msg;
this->numericUpDown6->Value = e->NewValue;
}
private: void checkBox3_CheckedChanged(Object * sender, System::EventArgs * e)
{
this->panel1->VisibleAutoScrollHorizontal = this->checkBox3->Checked;
}
private: void checkBox4_CheckedChanged(Object * sender, System::EventArgs * e)
{
this->panel1->VisibleAutoScrollVertical = this->checkBox4->Checked;
}
private: void panel1_ScrollMouseWheel(Object * sender, System::Windows::Forms::MouseEventArgs * e)
{
this->label4->Text = e->Delta.ToString();
this->numericUpDown6->Value = this->panel1->AutoScrollVPos;
}
private: void button3_Click(Object * sender, System::EventArgs * e)
{
this->panel1->performScrollHorizontal(ScrollEventType::LargeIncrement);
}
private: void button4_Click(Object * sender, System::EventArgs * e)
{
this->panel1->performScrollHorizontal(ScrollEventType::LargeDecrement);
}
private: void button1_Click(Object * sender, System::EventArgs * e)
{
this->panel1->performScrollVertical(ScrollEventType::LargeDecrement);
}
private: void button2_Click(Object * sender, System::EventArgs * e)
{
this->panel1->performScrollVertical(ScrollEventType::LargeIncrement);
}
private: void button5_Click(Object * sender, System::EventArgs * e)
{
this->panel1->performScrollVertical(ScrollEventType::SmallDecrement);
}
private: void button6_Click(Object * sender, System::EventArgs * e)
{
this->panel1->performScrollVertical(ScrollEventType::SmallIncrement);
}
private: void button7_Click(Object * sender, System::EventArgs * e)
{
this->panel1->performScrollHorizontal(ScrollEventType::SmallIncrement);
}
private: void button8_Click(Object * sender, System::EventArgs * e)
{
this->panel1->performScrollHorizontal(ScrollEventType::SmallDecrement);
}
private: void numericUpDown1_ValueChanged(Object * sender, System::EventArgs * e)
{
this->panel1->AutoScrollHorizontalMinimum = System::Convert::ToInt32( this->numericUpDown1->Value );
}
private: void numericUpDown2_ValueChanged(Object * sender, System::EventArgs * e)
{
this->panel1->AutoScrollHorizontalMaximum = System::Convert::ToInt32( this->numericUpDown2->Value );
}
private: void numericUpDown3_ValueChanged(Object * sender, System::EventArgs * e)
{
this->panel1->AutoScrollVerticalMinimum = System::Convert::ToInt32( this->numericUpDown3->Value );
}
private: void numericUpDown4_ValueChanged(Object * sender, System::EventArgs * e)
{
this->panel1->AutoScrollVerticalMaximum = System::Convert::ToInt32( this->numericUpDown4->Value );
}
private: void numericUpDown5_ValueChanged(Object * sender, System::EventArgs * e)
{
this->panel1->AutoScrollHPos = System::Convert::ToInt32( this->numericUpDown5->Value );
}
private: void numericUpDown6_ValueChanged(Object * sender, System::EventArgs * e)
{
this->panel1->AutoScrollVPos = System::Convert::ToInt32( this->numericUpDown6->Value );
}
private: void label11_Click(Object * sender, System::EventArgs * e)
{
this->panel1->Focus();
}
};
}
//=======================================
// Form1.cpp
//=======================================
#include "stdafx.h"
#include "Form1.h"
#include <windows.h>
using namespace ScrollPanel;
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
Application::Run(new Form1());
return 0;
}
//=======================================
// ScrollablePanel.h
//=======================================
namespace CustomAutoScrollPanel
{
using namespace System;
using namespace System::Windows::Forms;
using namespace System::Runtime::InteropServices ;
[DllImport("user32.dll", CharSet=CharSet::Auto)]
extern int GetSystemMetrics(int code);
[DllImport("user32.dll")]
extern bool EnableScrollBar(System::IntPtr hWnd, int wSBflags, int wArrows);
[DllImport("user32.dll")]
extern void SetScrollRange(System::IntPtr hWnd, int nBar, int nMinPos, int nMaxPos, bool bRedraw);
[DllImport("user32.dll")]
extern int SetScrollPos(System::IntPtr hWnd, int nBar, int nPos, bool bRedraw);
[DllImport("user32.dll")]
extern int GetScrollPos(System::IntPtr hWnd, int nBar);
[DllImport("user32.dll")]
extern bool PostMessageA(IntPtr hwnd, int wMsg, int wParam, int lParam);
[DllImport("user32.dll")]
extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);
[DllImport("user32.dll")]
extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll")]
extern int HIWORD(IntPtr wParam);
///
/// Description résumée de ScrollablePanel.
///
__gc class ScrollablePanel: public System::Windows::Forms::Panel
{
__value enum MYConsts1 {
SB_LINEUP = 0,
SB_LINEDOWN = 1,
SB_PAGEUP = 2,
SB_PAGEDOWN = 3,
SB_THUMBPOSITION = 4,
SB_THUMBTRACK = 5,
SB_TOP = 6,
SB_BOTTOM = 7,
SB_ENDSCROLL = 8 ,
WM_HSCROLL = 0x114,
WM_VSCROLL = 0x115,
WM_MOUSEWHEEL = 0x020A,
WM_NCCALCSIZE =0x0083,
WM_PAINT =0x000F,
WM_SIZE =0x0005 ,
SB_HORZ = 0,
SB_VERT = 1,
SB_CTL = 2,
SB_BOTH = 3 ,
ESB_DISABLE_BOTH = 0x3,
ESB_ENABLE_BOTH = 0x0 ,
MK_LBUTTON = 0x01,
MK_RBUTTON = 0x02,
MK_SHIFT = 0x04,
MK_CONTROL = 0x08,
MK_MBUTTON = 0x10,
MK_XBUTTON1 = 0x0020,
MK_XBUTTON2 = 0x0040
};
static bool enableAutoHorizontal = true;
static bool enableAutoVertical = true;
static bool visibleAutoHorizontal = true;
static bool visibleAutoVertical = true;
static int autoScrollHorizontalMinimum = 0;
static int autoScrollHorizontalMaximum = 100;
static int autoScrollVerticalMinimum = 0;
static int autoScrollVerticalMaximum = 100;
public:
__event System::Windows::Forms::ScrollEventHandler * ScrollHorizontal;
__event System::Windows::Forms::ScrollEventHandler * ScrollVertical;
__event System::Windows::Forms::MouseEventHandler * ScrollMouseWheel;
ScrollablePanel()
{
this->Click += new EventHandler(this, ScrollablePanel_Click);
this->AutoScroll = true;
}
__property int get_AutoScrollHPos() {
return GetScrollPos(this->Handle, SB_HORZ);
}
__property void set_AutoScrollHPos(int value) {
SetScrollPos(this->Handle, (int)SB_HORZ, value, true);
SetDisplayRectLocation(-value, -DisplayRectangle.Y);
}
__property int get_AutoScrollVPos() {
return GetScrollPos(this->Handle, 1);
}
__property void set_AutoScrollVPos(int value) {
SetScrollPos(this->Handle, (int)SB_VERT, value, true);
SetDisplayRectLocation(-DisplayRectangle.X, -value);
}
__property int get_AutoScrollHorizontalMinimum() {
return this->autoScrollHorizontalMinimum;
}
__property void set_AutoScrollHorizontalMinimum(int value) {
this->autoScrollHorizontalMinimum = value;
SetScrollRange(this->Handle, SB_HORZ,
autoScrollHorizontalMinimum,
autoScrollHorizontalMaximum, true);
}
__property int get_AutoScrollHorizontalMaximum() {
return autoScrollHorizontalMaximum;
}
__property void set_AutoScrollHorizontalMaximum(int value) {
autoScrollHorizontalMaximum = value;
SetScrollRange(this->Handle, (int)SB_HORZ,
this->autoScrollHorizontalMinimum,
this->autoScrollHorizontalMaximum, true);
}
__property int get_AutoScrollVerticalMinimum() {
return this->autoScrollVerticalMinimum;
}
__property void set_AutoScrollVerticalMinimum(int value) {
this->autoScrollVerticalMinimum = value;
SetScrollRange(this->Handle, (int)SB_VERT,
this->autoScrollHorizontalMinimum,
this->autoScrollHorizontalMaximum, true);
}
__property int get_AutoScrollVerticalMaximum() {
return this->autoScrollVerticalMaximum;
}
__property void set_AutoScrollVerticalMaximum(int value) {
this->autoScrollVerticalMaximum = value;
SetScrollRange(this->Handle, (int)SB_VERT,
this->autoScrollHorizontalMinimum,
this->autoScrollHorizontalMaximum, true);
}
__property bool get_EnableAutoScrollHorizontal() {
return this->enableAutoHorizontal;
}
__property void set_EnableAutoScrollHorizontal(bool value) {
this->enableAutoHorizontal = value;
if (value)
EnableScrollBar(this->Handle, SB_HORZ, ESB_ENABLE_BOTH);
else
EnableScrollBar(this->Handle, SB_HORZ, ESB_DISABLE_BOTH);
}
__property bool get_EnableAutoScrollVertical() {
return this->enableAutoVertical;
}
__property void set_EnableAutoScrollVertical(bool value) {
this->enableAutoVertical = value;
if (value)
EnableScrollBar(this->Handle, SB_VERT, ESB_ENABLE_BOTH);
else
EnableScrollBar(this->Handle, SB_VERT, ESB_DISABLE_BOTH);
}
__property bool get_VisibleAutoScrollHorizontal() {
return this->visibleAutoHorizontal;
}
__property void set_VisibleAutoScrollHorizontal(bool value) {
this->visibleAutoHorizontal = value;
ShowScrollBar(this->Handle, (int)SB_HORZ, value);
}
__property bool get_VisibleAutoScrollVertical() {
return this->visibleAutoVertical;
}
__property void set_VisibleAutoScrollVertical(bool value) {
this->visibleAutoVertical = value;
ShowScrollBar(this->Handle, (int)SB_VERT, value);
}
void performScrollHorizontal(ScrollEventType type)
{
int param = getSBFromScrollEventType(type);
if (param == -1)
return;
SendMessage(this->Handle, WM_HSCROLL, param, 0);
}
void performScrollVertical(ScrollEventType type)
{
int param = getSBFromScrollEventType(type);
if (param == -1)
return;
SendMessage(this->Handle, WM_VSCROLL, param, 0);
}
protected:
void WndProc(Message * msg)
{
__super::WndProc(msg);
if (msg->HWnd != this->Handle)
return;
switch (msg->Msg)
{
case WM_MOUSEWHEEL:
if (!this->VisibleAutoScrollVertical)
return;
{
int zDelta = HiWord((int)msg->WParam);
int y = HiWord((int)msg->LParam);
int x = LoWord((int)msg->LParam);
System::Windows::Forms::MouseButtons butt;
switch (LoWord((int)msg->WParam))
{
case MK_LBUTTON:
butt = System::Windows::Forms::MouseButtons::Left;
break;
case MK_MBUTTON:
butt = System::Windows::Forms::MouseButtons::Middle;
break;
case MK_RBUTTON:
butt = System::Windows::Forms::MouseButtons::Right;
break;
case MK_XBUTTON1:
butt = System::Windows::Forms::MouseButtons::XButton1;
break;
case MK_XBUTTON2:
butt = System::Windows::Forms::MouseButtons::XButton2;
break;
default:
butt = System::Windows::Forms::MouseButtons::None;
break;
}
System::Windows::Forms::MouseEventArgs * arg0 = new System::Windows::Forms::MouseEventArgs(butt, 1, x, y, zDelta);
this->ScrollMouseWheel(this, arg0);
}
break;
case WM_VSCROLL:
{
int x= GetScrollPos(this->Handle, (int)SB_VERT) ;
ScrollEventType type = getScrollEventType(msg->WParam);
ScrollEventArgs * arg = new ScrollEventArgs(type, x);
this->ScrollVertical(this, arg);
//------------------------------------------
// Following repeating code can increase
// the increment of Vertical Scroll
//------------------------------------------
__super::WndProc(msg);
x= GetScrollPos(this->Handle, (int)SB_VERT) ;
type = getScrollEventType(msg->WParam);
arg = new ScrollEventArgs(type, x);
this->ScrollVertical(this, arg);
__super::WndProc(msg);
x= GetScrollPos(this->Handle, (int)SB_VERT) ;
type = getScrollEventType(msg->WParam);
arg = new ScrollEventArgs(type, x);
this->ScrollVertical(this, arg);
__super::WndProc(msg);
x= GetScrollPos(this->Handle, (int)SB_VERT) ;
type = getScrollEventType(msg->WParam);
arg = new ScrollEventArgs(type, x);
this->ScrollVertical(this, arg);
__super::WndProc(msg);
x= GetScrollPos(this->Handle, (int)SB_VERT) ;
type = getScrollEventType(msg->WParam);
arg = new ScrollEventArgs(type, x);
this->ScrollVertical(this, arg);
}
break;
case WM_HSCROLL:
{
ScrollEventType type = getScrollEventType(msg->WParam);
ScrollEventArgs *arg = new ScrollEventArgs(type, GetScrollPos(this->Handle, (int)SB_HORZ));
this->ScrollHorizontal(this, arg);
}
break;
default:
break;
}
}
private:
int getSBFromScrollEventType(ScrollEventType type)
{
int res = -1;
switch (type)
{
case ScrollEventType::SmallDecrement:
res = SB_LINEUP;
break;
case ScrollEventType::SmallIncrement:
res = SB_LINEDOWN;
break;
case ScrollEventType::LargeDecrement:
res = SB_PAGEUP;
break;
case ScrollEventType::LargeIncrement:
res = SB_PAGEDOWN;
break;
case ScrollEventType::ThumbTrack:
res = SB_THUMBTRACK;
break;
case ScrollEventType::First:
res = SB_TOP;
break;
case ScrollEventType::Last:
res = SB_BOTTOM;
break;
case ScrollEventType::ThumbPosition:
res = SB_THUMBPOSITION;
break;
case ScrollEventType::EndScroll:
res = SB_ENDSCROLL;
break;
default:
break;
}
return res;
}
ScrollEventType getScrollEventType(System::IntPtr wParam)
{
ScrollEventType res = ScrollEventType::EndScroll;
switch (LoWord((int)wParam))
{
case SB_LINEUP:
res = ScrollEventType::SmallDecrement;
break;
case SB_LINEDOWN:
res = ScrollEventType::SmallIncrement;
break;
case SB_PAGEUP:
res = ScrollEventType::LargeDecrement;
break;
case SB_PAGEDOWN:
res = ScrollEventType::LargeIncrement;
break;
case SB_THUMBTRACK:
res = ScrollEventType::ThumbTrack;
break;
case SB_TOP:
res = ScrollEventType::First;
break;
case SB_BOTTOM:
res = ScrollEventType::Last;
break;
case SB_THUMBPOSITION:
res = ScrollEventType::ThumbPosition;
break;
case SB_ENDSCROLL:
res = ScrollEventType::EndScroll;
break;
default:
res = ScrollEventType::EndScroll;
break;
}
return res;
}
void ScrollablePanel_Click(Object * sender, EventArgs * e)
{
this->Focus();
}
int MakeLong(int LoWord, int HiWord)
{
return (HiWord << 16) | (LoWord & 0xffff);
}
IntPtr MakeLParam(int LoWord, int HiWord)
{
return (IntPtr) ((HiWord << 16) | (LoWord & 0xffff));
}
int HiWord(int number)
{
if ((number & 0x80000000) == 0x80000000)
return (number >> 16);
else
return (number >> 16) & 0xffff ;
}
int LoWord(int number)
{
return number & 0xffff;
}
};
}
|
|
|
|
|
I have panel with AutoScroll == true (now it's ScrollablePanel - thanks a lot). On this panel there is another panel with 3 grids. If they scrolled and I try to select one of them, all of them are jumping (up or down, to the very top or sometimes not). As I understand a Panel with scroll is responsible for this. Can I cancel this behavior? I'd like them to stay exactly in the same place I scrolled them.
|
|
|
|
|
As noted setting the range doesn't work which is what I'd really like to be able to control with an autoscroll panel. I tried running the test app and setting the range properties; it does what I would have tried (call SetScrollRange()). Hmmm...wonder why that doesn't work?
|
|
|
|
|
I'm having that problem now. The scroll position value in scroll event handlers is not bound to the specified range. Bummer
The MSDN article titled "Scroll Bars" details all the Win32 functions. The docs say that Get/SetScrollPos, Get/SetScrollRange have been replaced with Get/SetScrollInfo functions. I'll try that now...
|
|
|
|
|
Really simply and powerfull fix Thank you Mathew
Olivier Carpentier
Manalee
RichMedia solutions
|
|
|
|
|
This a good fix and with one correction it works as intended. This code inverts the unchanged value on every call, which results in a jumpy behaviour (some clipping seems to work behind the scenes too).
Just use
SetDisplayRectLocation(-value, DisplayRectangle.Y);
and
SetDisplayRectLocation(DisplayRectangle.X, -value);
instead and everything works fine.
|
|
|
|
|