|

Introduction
This article show how to customize a System.Windows.Forms.Panel
to use effectively scrollbars with the AutoScroll
property. In this example, you can change enable or visible property of each
scrollbar of the panel, receive scrolling events, send events to the panel and
change and receive the positions of both scrollbars.
Background
With .Net, use a panel with Autoscroll property is
really useful, but you can not receive events of scrollbars and personalize some
functionalities like visible or enable properties of only one scrollbar for
example.
Using the code
In your solution, add the file ScrollablePanel.cs to your C# project.
Then, you can change type of a panel in your project by the ScrollablePanel type. Sorry but I have no time to make a visual
component in a DLL.
Now you have new properties to your panel object:
int AutoScrollHPos: To get or set the horizontal
scrollbar position
int AutoScrollVPos: To get or set the vertical
scrollbar position
int AutoScrollHorizontalMinimum: To get or set the
horizontal scrollbar minimum range
int AutoScrollHorizontalMaximum: To get or set the
horizontal scrollbar maximum range
int AutoScrollVerticalMinimum: To get or set the
vertical scrollbar minimum range
int AutoScrollVerticalMaximum: To get or set the
vertical scrollbar maximum range
bool EnableAutoScrollHorizontal: Enable horizontal
scrollbar
bool EnableAutoScrollVertical: Enable vertical
scrollbar
bool VisibleAutoScrollHorizontal: Visible horizontal
scrollbar
bool VisibleAutoScrollVertical: Visible vertical
scrollbar
And your panel have now some new events:
public event System.Windows.Forms.ScrollEventHandler
ScrollHorizontal: receive when the horizontal scroll bar move
public event System.Windows.Forms.ScrollEventHandler
ScrollVertical: receive when the vertical scroll bar move
public event System.Windows.Forms.MouseEventHandler
ScrollMouseWheel: receive when mouse wheel move
Explanations about code in the ScrollablePanel
class:
First you must create a new class that overrode the System.Windows.Forms.Panel. So, you must override the WndProc function to receive API32 scrolling messages and then to
send .Net ScrollEvents.
protected override void WndProc(ref Message msg)
{
base.WndProc(ref msg);
if (msg.HWnd != this.Handle)
return;
switch (msg.Msg)
{
case WM_VSCROLL:
try
{
ScrollEventType type = getScrollEventType(msg.WParam);
ScrollEventArgs arg = new ScrollEventArgs(type,
GetScrollPos(this.Handle, (int)SB_VERT));
this.ScrollVertical(this, arg);
}
catch (Exception) { }
break;
case WM_HSCROLL:
try
{
ScrollEventType type = getScrollEventType(msg.WParam);
ScrollEventArgs arg = new ScrollEventArgs(type,
GetScrollPos(this.Handle, (int)SB_HORZ));
this.ScrollHorizontal(this, arg);
}
catch (Exception) { }
break;
default:
break;
}
}
Then, you can see that you are using two main functions: GetScrollPos and some const from Win32 API.
Analyze the source code to see how are calle the Win32 API functions, like it
for example: [DllImport("user32.dll")]
static public extern int GetScrollPos(System.IntPtr hWnd,
int nBar);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg,
UIntPtr wParam, IntPtr lParam);
...
Note that sometimes, you need the C++ MACRO to get HIWORD or LOWORD from a WParam of a message for example. I use these two functions that
seem to be good: private static int HiWord(int number)
{
if ((number & 0x80000000) == 0x80000000)
return (number >> 16);
else
return (number >> 16) & 0xffff ;
}
private static int LoWord(int number)
{
return number & 0xffff;
}
private static int MakeLong(int LoWord, int HiWord)
{
return (HiWord << 16) | (LoWord & 0xffff);
}
private static IntPtr MakeLParam(int LoWord, int HiWord)
{
return (IntPtr) ((HiWord << 16) | (LoWord & 0xffff));
}
That's all, enjoy with it in the hope that it will be useful for you...
History
- Version 1.0: receive all scrolling events and mouse wheel. Send scroll
events to your panel. Get or obtain the mouse wheel delta, and
ScrollEventType. The range doesn't look like to work for the
moment.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 46 (Total in Forum: 46) (Refresh) | FirstPrevNext |
|
 |
|
|
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
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
A panel with horizontal scrollbar is what bothered me so long.And your article helps me. Thank you so much.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
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!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
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?
|
| Sign In·View Thread·PermaLink | 2.89/5 (3 votes) |
|
|
|
 |
|
|
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
|
| Sign In·View Thread·PermaLink | 3.50/5 (2 votes) |
|
|
|
 |
|
|
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.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi there, I just tried out your app and added the following code to Form1's constructor:
for (int i = 0;i < 10; i++) { System.Windows.Forms.TextBox textBox = new System.Windows.Forms.TextBox(); textBox.Dock = DockStyle.Top; panel2.Controls.Add(textBox); }
And if I tab through the controls, your panel doesn't pick up on the scroll events.
Tim
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
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?
|
| Sign In·View Thread·PermaLink | 4.20/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
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.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
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!
|
| Sign In·View Thread·PermaLink | 2.67/5 (3 votes) |
|
|
|
 |
|
|
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.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
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!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Can you send me the bug fixes too? cyrus at whozin dot com Thanks!
---------------------------------------------------- I do believe in monsters, I call them officers....
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
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
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
//================================== // 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
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) {< | | | | | |