 |
|
 |
I have used this scrollable (only vertical)ListBox for my project developed in windows XP and it's working perfectly. but, when i run my application in windows Vista, the scrolling is not working. The scrolling arrow-mark in the listbox is getting vanished after first scroll in windows Vista theme.
Can anybody help me, with any idea to solve this issue ??
|
|
|
|
 |
|
 |
For reference, it turns out that the scroll position is sent with SB_THUMBPOSITION and SB_THUMBTRACK, it just has to be extracted from the wParam.
The MSDN documentation says:
"nPos
Value of the high-order word of wParam. Specifies the current position of the scroll box if the nScrollCode parameter is SB_THUMBPOSITION or SB_THUMBTRACK; otherwise, nPos is not used."
The scroll position is the "high-order word of wParam". Also, the scroll code is sent in the low-order word of the wParam, so it might be best to extract the low word from the wParam and determine the scroll type that way, instead of looking at the entire wParam. Here are C# equivalents of the HIWORD and LOWORD C macros which you can use to get the scroll position and scroll code out of the wParam.
public static short LOWORD(int dWord)
{
return (short)dWord;
}
public static short HIWORD(int dWord)
{
return (short)(dWord >> 16);
}
|
|
|
|
 |
|
 |
private const int SB_HORZ = 1; private const int WM_MOUSEWHEEL = 0x20A; .... protected override void WndProc(ref Message msg) { if (msg.Msg == WM_VSCROLL || msg.Msg == WM_MOUSEWHEEL) { if (Scrolled != null) { ScrollInfoStruct si = new ScrollInfoStruct(); si.fMask = SIF_ALL; si.cbSize = Marshal.SizeOf(si); GetScrollInfo(msg.HWnd, SB_HORZ, ref si); if (msg.WParam.ToInt32() == SB_ENDSCROLL || msg.Msg == WM_MOUSEWHEEL) { ScrollEventArgs sargs = new ScrollEventArgs( ScrollEventType.EndScroll, si.nPos); Scrolled(this, sargs); } } } base.WndProc(ref msg); }
|
|
|
|
 |
|
 |
I'm getting the
msg.WParam.ToInt32() == SB_ENDSCROLL
but the si.nPos is always zero...
protected override void WndProc(ref System.Windows.Forms.Message msg)
{
if (msg.Msg == WM_VSCROLL)
{
base.WndProc(ref msg);
if (Scroll != null)
{
SCROLLINFO si = new SCROLLINFO();
si.fMask = SIF_POS;
si.cbSize = Convert.ToUInt32(Marshal.SizeOf(si));
si.nMax = 5000;
GetScrollInfo(msg.HWnd, 0, ref si);
if (msg.WParam.ToInt32() == SB_ENDSCROLL)
{
ScrollEventArgs sargs = new ScrollEventArgs(ScrollEventType.EndScroll, si.nPos );
Scroll(this, sargs);
}
}
}
else
base.WndProc(ref msg);
}
|
|
|
|
 |
|
 |
Change the 0 (Hort Scroll) to 1 (Vert Scroll)
Before:
GetScrollInfo(msg.HWnd, 0, ref si);
After:
GetScrollInfo(msg.HWnd, 1, ref si);
|
|
|
|
 |
|
 |
Here is VB Code for the ScrollingListBox Class:
Imports system
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Data
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Public Class ScrollingListBox
Inherits System.Windows.Forms.ListBox
Private components As System.ComponentModel.Container = Nothing
_
Public Event Scrolled As ScrollEventHandler
Private Const WM_HSCROLL As Integer = &H114
Private Const WM_VSCROLL As Integer = &H115
Private Const SB_LINELEFT As Integer = 0
Private Const SB_LINERIGHT As Integer = 1
Private Const SB_PAGELEFT As Integer = 2
Private Const SB_PAGERIGHT As Integer = 3
Private Const SB_THUMBPOSITION As Integer = 4
Private Const SB_THUMBTRACK As Integer = 5
Private Const SB_LEFT As Integer = 6
Private Const SB_RIGHT As Integer = 7
Private Const SB_ENDSCROLL As Integer = 8
Private Const SIF_TRACKPOS As Integer = &H10
Private Const SIF_RANGE As Integer = &H1
Private Const SIF_POS As Integer = &H4
Private Const SIF_PAGE As Integer = &H2
Private Const SIF_ALL As Integer = (SIF_RANGE Or SIF_PAGE Or SIF_POS Or SIF_TRACKPOS)
Private Structure ScrollInfoStruct
Public cbSize As Integer
Public fMask As Integer
Public nMin As Integer
Public nMax As Integer
Public nPage As Integer
Public nPos As Integer
Public nTrackPos As Integer
End Structure
_
Private Shared Function GetScrollInfo(ByRef hWnd As Integer, ByVal n As Integer, ByRef lpScrollInfo As ScrollInfoStruct) As Integer
End Function
Protected Overrides Sub WndProc(ByRef msg As System.Windows.Forms.Message)
Dim si As New ScrollInfoStruct
If msg.Msg = WM_VSCROLL Then
'If Scrolled Is System.DBNull.Value = False Then
si.fMask = SIF_ALL
si.cbSize = Marshal.SizeOf(si)
GetScrollInfo(msg.HWnd, 0, si)
If (msg.WParam.ToInt32() = SB_ENDSCROLL) Then
Dim sargs As New ScrollEventArgs(ScrollEventType.EndScroll, _
si.nPos)
RaiseEvent Scrolled(Me, sargs)
End If
'End If
End If
MyBase.WndProc(msg)
End Sub
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
'Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
End Class
|
|
|
|
 |
|
 |
Appears this is an error
Private Shared Function GetScrollInfo(ByRef hWnd As Integer, ByVal n As Integer, ByRef lpScrollInfo As ScrollInfoStruct) As Integer
End Function
Should be:
Private Declare Function GetScrollInfo Lib "user32" (ByVal hWnd As IntPtr, ByVal n As Integer, ByRef lpScrollInfo As ScrollInfoStruct) As Integer
|
|
|
|
 |
|
 |
Hi.
How do you add a custom made control to the Form1 in design view?
I cannot find it on the Toolbox pane and I could not find it when trying to add it to the Toolbar pan.
I cannot figure it out. (sorry%#&!)
/Thomas
|
|
|
|
 |
|
 |
Hi
I want to know how to add horizontal scallbar in listbox with asp.net and vb script
thank you.
|
|
|
|
 |
|
 |
hi
How can i get the sroll events of an apllication invoked by our program.eg.
i got code for trackking some events of MSWord,but i need both horizontal and vertical events to be track.
lkr
|
|
|
|
 |
|
 |
First of all, this is very helpful code.
Second, I'd like to apply this code to the MS Web browser control to have it fire events when scrolling occurs but can't seem to get it to work. It appears that the WM_HSCROLL messages never occur.
Am I missing something or can we not do this with the web browser control?
Thanks.
|
|
|
|
 |
|
 |
I meet the problem too, how can it works with the web browser control?
|
|
|
|
 |
|
 |
When i read a position of scroll i save it, and later want to set scrollposition on the same position.
So, how do i set position of scroll?
|
|
|
|
 |
|
 |
Ya.. Anyone know how to set the scroll position ?
|
|
|
|
 |
|
|
 |
|
 |
My goal was to expose a scroll event out of controls (treeview / datagrid) and keep them in sync vertically. I derived from the ScrollEventArgs normally returned by scroll events (from scrollbars), and added a Horizontal/Vertical enum, plus a percent of max (the idea of a percent max is flawed, because the size of the thumb's page gets in the way. So percent never reaches 1). Then when I saw a WM_HSCROLL or WM_VSCROLL out of the control, I would raise my own event. The listener of this event up in the form then told the sibling control to set its scrollbar to the same place. The problem I had was that the scrollbar would move, but the base control wouldn't reflect that. (I was calling SetScrollInfo directly, and noticed that the parent control's WndProc was never called. My guess is I need to send some sort of "SyncYourself" message.) While searching for an answer, I ran across the article "TreeListView" here in CodeProject. This control is much better suited for what I need to do, so I'm abandoning this multi-control syncing. However, the utility I put together to turn a raw WM_HSCROLL/WM_VSCROLL event into a .net friendly scroll event could still be usefull to people. I'm going to respond to this, and try to paste the .cs file (we'll see if there is a size limit on these messages)
|
|
|
|
 |
|
 |
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
// TODO: Change this namespace to whatever namespace your project is
namespace ScrollExposed
{
#region Public Enums
public enum ScrollEventOrientation
{
Horizontal = 0,
Vertical
};
#endregion
#region Interface: IScrollExposed
///
/// When you derive a control, and want to expose scroll events (using this utility as a helper), have
/// the control implement this interface to give things a consistent look.
///
public interface IScrollExposed
{
// I wanted to call this event Scroll, which is what the horizontal and vertical scroll bars expose. However,
// DataGrid already exposes that event, but it only passes an EventArg, not even a ScrollEventArg, which
// basically makes it useless. (on a side note for the data grid, you can get at its scrollbars directly through
// the Controls property)
//
// If you really want to go nuts, you could make two events: Before and After. It just depends whether you
// raise the event before or after the call to base.WndProc(ref msg);
event ScrollEventHandlerExpanded ScrollExpanded;
// These allow the user of controls to work with the scrollbars without worrying about min/max/value. (or
// even how the scrollbars are implemented internally) I have a felling that a major use of all this scroll
// exposure is to keep 2 or more controls lined up (treeview lined up vertically with a grid).
//
// Here's the case I'm trying to make work:
// There is a treeview on the left, and a grid on the right. The rows of the grid line up with the nodes of the
// treeview (when they expand a node, rows are inserted; collapse causes rows to be deleted). So when the
// user vertically scrolls the treeview or grid, the other needs to stay in sync. Since my scroll event exposes a
// percent, all I need to do is call the set of the other control.
double ScrollBarPercentOfMaxHorizontal
{
get;
set;
}
double ScrollBarPercentOfMaxVertical
{
get;
set;
}
}
#endregion
#region Delegate: ScrollEventHandlerExpanded
public delegate void ScrollEventHandlerExpanded(object sender, ScrollEventArgsExpanded e);
#endregion
#region Class: ScrollEventArgsExpanded
public class ScrollEventArgsExpanded : ScrollEventArgs
{
private ScrollEventOrientation _orientation;
private double _percentOfMax;
public ScrollEventArgsExpanded(ScrollEventOrientation orientation, ScrollEventType type, int newValue, double percentOfMax) : base(type, newValue)
{
_orientation = orientation;
_percentOfMax = percentOfMax;
}
///
/// Tells you what direction the user was scrolling to fire this event
///
public ScrollEventOrientation Orientation
{
get
{
return _orientation;
}
}
///
/// This goes from 0 to 1, and tells how far along the scroll bar is:
/// (Value - Min) / (Max - Min)
///
///
/// This will most likely never be 1. The width of the trackbar gets in the way. However, for keeping 2
/// controls in sync, that shouldn't matter.
///
public double PercentOfMax
{
get
{
return _percentOfMax;
}
}
}
#endregion
#region Class: ScrollUtility
///
/// Several helper functions to change a WndProc message into scroll events
///
///
/// Within your derived control, override WndProc. If the m.Msg equals WM_HSCROLL or WM_VSCROLL, then
/// you can use the helper functions within this class to turn the rest of msg into scroll event args
///
public class ScrollUtility
{
#region Declaration Section
//-------------------------- These constants came from C:\Program Files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\Include\WinUser.h
//
// These are constants that tell you what the m.Msg in WndProc is. ex:
// if(m.Msg == ScrollUtility.WM_HSCROLL)
public const int WM_HSCROLL = 0x114;
public const int WM_VSCROLL = 0x115;
// These are constants that help me decipher the rest of the message from WndProc
private const int SB_LINEUP = 0;
private const int SB_LINELEFT = 0;
private const int SB_LINEDOWN = 1;
private const int SB_LINERIGHT = 1;
private const int SB_PAGEUP = 2;
private const int SB_PAGELEFT = 2;
private const int SB_PAGEDOWN = 3;
private const int SB_PAGERIGHT = 3;
private const int SB_THUMBPOSITION = 4;
private const int SB_THUMBTRACK = 5;
private const int SB_TOP = 6;
private const int SB_LEFT = 6;
private const int SB_BOTTOM = 7;
private const int SB_RIGHT = 7;
private const int SB_ENDSCROLL = 8;
// These are constants that help me call GetScrollInfo (which gives me information about scrollbar position)
private const int SB_HORZ = 0;
private const int SB_VERT = 1;
private const int SB_CTL = 2;
private const int SIF_TRACKPOS = 0x10;
private const int SIF_RANGE = 0x1;
private const int SIF_POS = 0x4;
private const int SIF_PAGE = 0x2;
private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS;
[DllImport("user32.dll", SetLastError=true)]
private static extern int GetScrollInfo( IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo );
[DllImport("user32.dll", SetLastError=true)]
private static extern int SetScrollInfo( IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo, bool fRedraw );
private struct ScrollInfoStruct
{
public int cbSize;
public int fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
}
#endregion
#region GetNewScrollEventArgsExpanded
public static ScrollEventArgsExpanded GetNewScrollEventArgsExpanded(Message m)
{
// These are the values that make up the return class
ScrollEventOrientation orientation;
ScrollEventType type;
int newValue;
double percentOfMax;
int getscrollinfoOrientationParam;
// Figure out the orientation
switch (m.Msg)
{
case WM_HSCROLL:
orientation = ScrollEventOrientation.Horizontal;
getscrollinfoOrientationParam = SB_HORZ; // This assumes the control has a default horizonal scrollbar. If that's not the case, you might have to get more elaborite
break;
case WM_VSCROLL:
orientation = ScrollEventOrientation.Vertical;
getscrollinfoOrientationParam = SB_VERT; // This assumes the control has a default vertical scrollbar. If that's not the case, you might have to get more elaborite
break;
default:
throw new ArgumentOutOfRangeException("m.Msg", m.Msg, "Only WM_HSCROLL and WM_VSCROLL are supported");
}
// Now I can call GetScrollInfo
ScrollInfoStruct scrollInfo = GetScrollInfoStruct(m.HWnd, getscrollinfoOrientationParam);
// Figure out the type
switch (LOWORD(m.WParam.ToInt32())) // I need to pull the loword of the integer, because ThumbPos and ThumbTrack use the hiword of the integer for something else
{
case SB_THUMBPOSITION:
type = ScrollEventType.ThumbPosition;
break;
case SB_THUMBTRACK:
type = ScrollEventType.ThumbTrack;
break;
case SB_ENDSCROLL:
type = ScrollEventType.EndScroll;
break;
case SB_TOP: // SB_LEFT is the same value
type = ScrollEventType.First;
break;
case SB_BOTTOM: // SB_RIGHT is the same value
type = ScrollEventType.Last;
break;
case SB_PAGEUP: // SB_PAGELEFT is the same value
type = ScrollEventType.LargeDecrement;
break;
case SB_PAGEDOWN: // SB_PAGERIGHT is the same value
type = ScrollEventType.LargeIncrement;
break;
case SB_LINEUP: // SB_LINELEFT is the same value
type = ScrollEventType.SmallDecrement;
break;
case SB_LINEDOWN: // SB_LINERIGHT is the same value
type = ScrollEventType.SmallIncrement;
break;
default:
throw new ArgumentOutOfRangeException("LOWORD(m.WParam.ToInt32())", LOWORD(m.WParam.ToInt32()), "One of SB_ENDSCROLL, SB_THUMBTRACK, etc (between 0 and 8)");
}
// Figure out the value and percent of max
percentOfMax = GetPercentOfMax(scrollInfo.nPos, scrollInfo.nMin, scrollInfo.nMax);
newValue = scrollInfo.nPos;
// Exit Function
return new ScrollEventArgsExpanded(orientation, type, newValue, percentOfMax);
}
#endregion
#region Get/Set ScrollBarPercentOfMax
public static double GetScrollBarPercentOfMaxHorizontal(IntPtr handle)
{
ScrollInfoStruct scrollInfo = GetScrollInfoStruct(handle, SB_HORZ);
return GetPercentOfMax(scrollInfo.nPos, scrollInfo.nMin, scrollInfo.nMax);
}
public static double GetScrollBarPercentOfMaxVertical(IntPtr handle)
{
ScrollInfoStruct scrollInfo = GetScrollInfoStruct(handle, SB_VERT);
return GetPercentOfMax(scrollInfo.nPos, scrollInfo.nMin, scrollInfo.nMax);
}
public static void SetScrollBarPercentOfMaxHorizontal(IntPtr handle, double percent)
{
SetScrollBarPercentOfMax(handle, percent, SB_HORZ);
}
public static void SetScrollBarPercentOfMaxVertical(IntPtr handle, double percent)
{
SetScrollBarPercentOfMax(handle, percent, SB_VERT);
}
private static void SetScrollBarPercentOfMax(IntPtr handle, double percent, int orientation)
{
// Grab a scroll info structure
ScrollInfoStruct scrollInfo = GetScrollInfoStruct(handle, orientation);
// Set the position to something new
scrollInfo.nPos = Convert.ToInt32(Math.Round(Convert.ToDouble(scrollInfo.nMax - scrollInfo.nMin) * percent));
// Make sure it's not out of range (the user needs to pass in a percent from 0 to 1). Even then, there
// may be some mathmatical error
if(scrollInfo.nPos < scrollInfo.nMin)
{
scrollInfo.nPos = scrollInfo.nMin;
}
else if(scrollInfo.nPos > scrollInfo.nMax)
{
scrollInfo.nPos = scrollInfo.nMax;
}
// I don't want to set everything, just position
scrollInfo.fMask = SIF_POS;
// Tell the control to go to this new position
SetScrollInfo(handle, orientation, ref scrollInfo, true); // It may not need to be byref
}
#endregion
#region Private Support Functions
private static int LOWORD(int value32)
{
return value32 & 0xFFFF;
}
private static int LOWORD(IntPtr valuePtr)
{
return LOWORD(valuePtr.ToInt32());
}
private static int HIWORD(int value32)
{
throw new ApplicationException("Downloaded from VB example. Ported to C#, but needs testing");
//Public Function HIWORD(ByRef pintValue As Int32) As Int32
// If (pintValue And &H80000000) = &H80000000 Then
// Return ((pintValue And &H7FFF0000) \ &H10000) Or &H8000&
// Else
// Return (pintValue And &HFFFF0000) \ &H10000
// End If
//End Function
if ((value32 & 0x80000000) == 0x80000000)
{
return ((value32 & 0x7FFF0000) / 0x10000) | 0x8000;
}
else
{
return Convert.ToInt32((value32 & 0xFFFF0000) / 0x10000);
}
}
private static double GetPercentOfMax(int position, int min, int max)
{
double retVal = Convert.ToDouble(position - min) / Convert.ToDouble(max - min);
// Since this function is a helper to the custom controls, this can be called at design time. So I
// need this if statement here. Note: using (retVal == Double.NaN) doesn't work.
if(Double.IsNaN(retVal))
{
return 0;
}
else
{
return retVal;
}
}
///
/// Fills up a ScrollInfoStruct
///
/// The handle to the control
/// SB_HORZ or SB_VERT or maybe SB_CTL
/// Tells you where the scroll position is (plus min and max of the scrollbar)
private static ScrollInfoStruct GetScrollInfoStruct(IntPtr handle, int orientation)
{
// Make the shell of the structure (set two of the elements that form the question)
ScrollInfoStruct retVal = new ScrollInfoStruct();
retVal.fMask = SIF_ALL;
retVal.cbSize = Marshal.SizeOf(retVal);
// Ask for the rest of the structure to be filled out (based on what I just set up)
GetScrollInfo(handle, orientation, ref retVal);
// Exit Function
return retVal;
}
#endregion
}
#endregion
}
|
|
|
|
 |
|
 |
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; namespace ScrollExposed { public class ListboxScrollEvents : System.Windows.Forms.ListBox, IScrollExposed { // The scroll event that I expose to the world (raised for both horizontal and vertical scrolling) public event ScrollEventHandlerExpanded ScrollExpanded = null; #region Auto Form Stuff /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public ListboxScrollEvents() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion #endregion public double ScrollBarPercentOfMaxHorizontal { get { return ScrollUtility.GetScrollBarPercentOfMaxHorizontal(base.Handle); } set { ScrollUtility.SetScrollBarPercentOfMaxHorizontal(base.Handle, value); } } public double ScrollBarPercentOfMaxVertical { get { return ScrollUtility.GetScrollBarPercentOfMaxVertical(base.Handle); } set { ScrollUtility.SetScrollBarPercentOfMaxVertical(base.Handle, value); } }
protected override void WndProc(ref Message m) { // I will do this before I raise any events to get the final scroll position base.WndProc(ref m); // See if this is a scroll event if(m.Msg == ScrollUtility.WM_HSCROLL || m.Msg == ScrollUtility.WM_VSCROLL) { // I need to raise an event. See if there is anybody listening if(ScrollExpanded != null) { // I need to raise a dotnet friendly scroll event. Build up my args. ScrollEventArgsExpanded arg = ScrollUtility.GetNewScrollEventArgsExpanded(m); // I have my argument. Tell the world. ScrollExpanded(this, arg); } } }
} }
|
|
|
|
 |
|
 |
Hi,
Can this code be used for commercial purpose. If Yes, what is the license agreement for it
Dhawal
|
|
|
|
 |
|
 |
I was reading through what I posted, and realized that I forgot to check the "Do not treat <'s as HTML tags", so all the xml comments above the functions are lost. When you see something like: /// /// Several helper functions to change a WndProc message into scroll events /// /// /// Within your derived control, override WndProc. If the m.Msg equals WM_HSCROLL or WM_VSCROLL, then /// you can use the helper functions within this class to turn the rest of msg into scroll event args ///
It should have been: /// <summary> /// Several helper functions to change a WndProc message into scroll events /// </summary> /// <remarks> /// Within your derived control, override WndProc. If the m.Msg equals WM_HSCROLL or WM_VSCROLL, then /// you can use the helper functions within this class to turn the rest of msg into scroll event args /// </remarks>
|
|
|
|
 |
|
 |
I used your code. I'm trying to sync scrolling between two listboxes. so when the first one scrolls, the second scrolls also.
Code:
private void listBox1_ScrollExpanded(object sender, ScrollExposed.ScrollEventArgsExpanded e)
{
if (e.Orientation == ScrollEventOrientation.Horizontal)
{
listBox2.ScrollBarPercentOfMaxHorizontal = e.PercentOfMax;
}
else
{
listBox2.ScrollBarPercentOfMaxVertical = e.PercentOfMax;
}
}
When I do this, the scroll bar on the 2nd listbox does move, however the contents of the listbox don't change. Any ideas what I'm doing wrong? Thanks
|
|
|
|
 |
|
 |
try this:
ListBox2.TopIndex = ListBox1.TopIndex;
More info about "ListBox.TopIndex" property find in your VS help.
|
|
|
|
 |
|
 |
Can you do this both ways? I assume yes.
|
|
|
|
 |
|
 |
I try to synchronize two textbox but I got the same problem : the scrollbars move but not the content.
The TextBox doesn't have "TopIndex" property... is it possible to scroll the content ?
|
|
|
|
 |
|
 |
first of all I want to say, that this is a very useful code. I use this sample to reposition another control, every time the listbox content has been moved horizontally.
After calling
GetScrollInfo(msg.HWnd, 0, ref si);
si.nPos seems to contain the originally position not the target position.
e.g: When I hit the right arrow key the first time I get Position 0. When hit the right arrow key the second time I get Position 6.
Is there a way to get the target position (=Position 6 after the first hit)?
|
|
|
|
 |