Thread View: borland.public.cppbuilder.nativeapi
7 messages
7 total messages
Started by JD
Sat, 22 Apr 2006 10:06
WM_MOUSEMOVE
Author: JD
Date: Sat, 22 Apr 2006 10:06
Date: Sat, 22 Apr 2006 10:06
132 lines
5713 bytes
5713 bytes
I've subclassed a ListView's Header WndProc and the problem I'm
having is (I think) with WM_MOUSEMOVE. More specifically, when
moving the mouse over any of the Column's right boundry, the
cursor changes to crSizeAll and I don't get how because I'm not
passing on the message for processing.
How does it know to change the cursor and how can I change this
behavior?
Minimal sample:
#include "MyListView.h"
//--------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
new TMyListView( this );
}
//--------------------------------------------------------------
//--------------------------------------------------------------
#ifndef MyListViewH
#define MyListViewH
//--------------------------------------------------------------
#include <Classes.hpp>
#include <ComCtrls.hpp>
//--------------------------------------------------------------
#ifdef STRICT
#define HEADERWNDPROC WNDPROC
#else
#define HEADERWNDPROC FARPROC
#endif
//--------------------------------------------------------------
class TMyListView : public TListView
{
private:
typedef TListView inherited;
HWND hHeader;
LONG HeaderWndProcPtr;
HEADERWNDPROC OldHeaderWndProc;
void __fastcall HeaderWndProc( TMessage &Message );
void __fastcall SubclassHeaderWndProc();
void __fastcall HeaderMouseMove( TShiftState Shift, int X, int Y );
MESSAGE void __fastcall CMRecreateWnd( TMessage &Message );
public:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER( CM_RECREATEWND, TMessage, CMRecreateWnd )
END_MESSAGE_MAP( inherited )
public:
__fastcall TMyListView( TComponent* Owner );
__fastcall ~TMyListView();
};
//--------------------------------------------------------------
#endif
//--------------------------------------------------------------
#pragma hdrstop
#include "MyListView.h"
#include "shlwapi.h"
#pragma package(smart_init)
//--------------------------------------------------------------
__fastcall TMyListView::TMyListView(TComponent* Owner) : TListView( Owner )
{
Parent = dynamic_cast<TWinControl*>( Owner );
Align = alClient;
ShowColumnHeaders = true;
ViewStyle = vsReport;
TListColumn *pColumn;
for( int x = 0; x < 3; ++x )
{
pColumn = Columns->Add();
pColumn->Caption = "Column " + IntToStr(x);
pColumn->Width = (Width - 20) / 3;
}
TListItem *pItem;
for( int x = 0; x < 3; ++x )
{
pItem = Items->Add();
pItem->Caption = "Col " + IntToStr(0) + " ,Row " + IntToStr(x);
for( int y = 0; y < Columns->Count; ++y )
{
pItem->SubItems->Add("Col " + IntToStr(y+1) + " ,Row " + IntToStr(x));
}
}
HeaderWndProcPtr = reinterpret_cast<LONG>( MakeObjectInstance(HeaderWndProc) );
SubclassHeaderWndProc();
}
//--------------------------------------------------------------
__fastcall TMyListView::~TMyListView()
{
if( hHeader ) ::SetWindowLong( hHeader, GWL_WNDPROC, reinterpret_cast<LONG>(OldHeaderWndProc) );
FreeObjectInstance( reinterpret_cast<void*>(HeaderWndProcPtr) );
}
//--------------------------------------------------------------
MESSAGE void __fastcall TMyListView::CMRecreateWnd( TMessage &Message )
{
inherited::Dispatch( &Message );
SubclassHeaderWndProc();
}
//--------------------------------------------------------------
void __fastcall TMyListView::SubclassHeaderWndProc()
{
hHeader = ListView_GetHeader( Handle );
if( hHeader ) OldHeaderWndProc = reinterpret_cast<HEADERWNDPROC>( ::SetWindowLong(hHeader, GWL_WNDPROC, HeaderWndProcPtr) );
}
//--------------------------------------------------------------
void __fastcall TMyListView::HeaderWndProc( TMessage &Message )
{
switch( Message.Msg )
{
case WM_MOUSEMOVE: HeaderMouseMove( KeysToShiftState(Message.WParam), LOWORD(Message.LParam), HIWORD(Message.LParam) );
Message.Result = 0;
return;
case WM_DESTROY: Message.Result = ::CallWindowProc(OldHeaderWndProc, hHeader, Message.Msg, Message.WParam, Message.LParam );
::SetWindowLong( hHeader, GWL_WNDPROC, reinterpret_cast<LONG>(OldHeaderWndProc) );
hHeader = NULL;
return;
}
Message.Result = ::CallWindowProc( OldHeaderWndProc, hHeader, Message.Msg, Message.WParam, Message.LParam );
}
//--------------------------------------------------------------
void __fastcall TMyListView::HeaderMouseMove( TShiftState Shift, int X, int Y )
{
//
}
//--------------------------------------------------------------
~ JD
Re: WM_MOUSEMOVE
Author: JD
Date: Sat, 22 Apr 2006 11:25
Date: Sat, 22 Apr 2006 11:25
8 lines
953 bytes
953 bytes
"JD" <nospam@nospam.com> wrote: > > [...] (I think) with WM_MOUSEMOVE. I should have been looking for is WM_SETCURSOR. ~ JD
Re: WM_MOUSEMOVE
Author: Remy Lebeau (TeamB)
Date: Mon, 24 Apr 2006 18:57
Date: Mon, 24 Apr 2006 18:57
156 lines
5974 bytes
5974 bytes
"JD" <nospam@nospam.com> wrote in message
news:444a0026$1@newsgroups.borland.com...
> Minimal sample:
Just an FYI, since you are now using a descendant class to manage the
subclassing, you can do so much more efficiently by not intercepting the
CM_RECREATEWND message at all. Use the virtual CreateWnd() and DestroyWnd()
methods instead. For example:
--- Unit1.cpp ---
#include "MyListView.h"
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TMyListView *lv = new TMyListView(this);
lv->Parent = this;
lv->Align = alClient;
TListColumn *pColumn;
for(int x = 0; x < 3; ++x)
{
pColumn = lv->Columns->Add();
pColumn->Caption = "Column " + IntToStr(x);
pColumn->Width = (lv->Width - 20) / 3;
}
TListItem *pItem;
for(int x = 0; x < 3; ++x)
{
pItem = lv->Items->Add();
pItem->Caption = "Col " + IntToStr(0) + ", Row " + IntToStr(x);
for(int y = 0; y < lv->Columns->Count; ++y)
pItem->SubItems->Add("Col " + IntToStr(y+1) + ", Row " +
IntToStr(x));
}
}
--- MyListView.h ---
//--------------------------------------------------------------
#ifndef MyListViewH
#define MyListViewH
//--------------------------------------------------------------
#include <Classes.hpp>
#include <ComCtrls.hpp>
//--------------------------------------------------------------
#ifdef STRICT
#define HEADERWNDPROC WNDPROC
#else
#define HEADERWNDPROC FARPROC
#endif
//--------------------------------------------------------------
class TMyListView : public TListView
{
typedef TListView inherited;
private:
HWND hHeader;
LONG HeaderWndProcPtr;
HEADERWNDPROC OldHeaderWndProc;
void __fastcall HeaderWndProc(TMessage &Message);
protected:
virtual void __fastcall CreateWnd();
virtual void __fastcall DestroyWnd();
virtual void __fastcall HeaderMouseMove(TShiftState Shift, int X,
int Y);
public:
__fastcall TMyListView(TComponent* Owner);
__fastcall ~TMyListView();
};
//--------------------------------------------------------------
#endif
//--------------------------------------------------------------
#pragma hdrstop
#include "MyListView.h"
#include "shlwapi.h"
#pragma package(smart_init)
//--------------------------------------------------------------
__fastcall TMyListView::TMyListView(TComponent* Owner)
: TListView(Owner)
{
ShowColumnHeaders = true;
ViewStyle = vsReport;
HeaderWndProcPtr =
reinterpret_cast<LONG>(MakeObjectInstance(HeaderWndProc));
}
//--------------------------------------------------------------
__fastcall TMyListView::~TMyListView()
{
FreeObjectInstance(reinterpret_cast<void*>(HeaderWndProcPtr));
}
//--------------------------------------------------------------
void __fastcall TMyListView::CreateWnd()
{
inherited::CreateWnd();
if( HandleAllocated() )
{
hHeader = ListView_GetHeader(Handle);
if( hHeader )
OldHeaderWndProc =
reinterpret_cast<HEADERWNDPROC>(::SetWindowLong(hHeader, GWL_WNDPROC,
HeaderWndProcPtr));
}
}
//--------------------------------------------------------------
void __fastcall TMyListView::DestroyWnd()
{
if( hHeader )
{
::SetWindowLong(hHeader, GWL_WNDPROC,
reinterpret_cast<LONG>(OldHeaderWndProc));
hHeader = NULL;
OldHeaderWndProc = NULL;
}
inherited::DestroyWnd();
}
//--------------------------------------------------------------
void __fastcall TMyListView::HeaderWndProc(TMessage &Message)
{
switch( Message.Msg )
{
case WM_MOUSEMOVE:
HeaderMouseMove(KeysToShiftState(Message.WParam),
LOWORD(Message.LParam), HIWORD(Message.LParam));
Message.Result = 0;
break;
case WM_DESTROY:
::SetWindowLong(hHeader, GWL_WNDPROC,
reinterpret_cast<LONG>(OldHeaderWndProc));
Message.Result = ::CallWindowProc(OldHeaderWndProc, hHeader,
Message.Msg, Message.WParam, Message.LParam);
hHeader = NULL;
OldHeaderWndProc = NULL;
break;
default:
Message.Result = ::CallWindowProc(OldHeaderWndProc, hHeader,
Message.Msg, Message.WParam, Message.LParam);
break;
}
}
//--------------------------------------------------------------
void __fastcall TMyListView::HeaderMouseMove(TShiftState Shift, int X,
int Y)
{
//
}
//--------------------------------------------------------------
Gambit
Re: WM_MOUSEMOVE
Author: JD
Date: Tue, 25 Apr 2006 11:31
Date: Tue, 25 Apr 2006 11:31
12 lines
1232 bytes
1232 bytes
"Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> wrote: > > [...] since you are now using a descendant [...] Use the > virtual CreateWnd() and DestroyWnd() methods instead. Believe it or not, that *was* on my to-do list! Thanks for the sample. Now it's just cut-n-paste. OT: Are you aware of any bugs with the underlying MS ListView? ~ JD
Re: WM_MOUSEMOVE
Author: Remy Lebeau (TeamB)
Date: Tue, 25 Apr 2006 16:58
Date: Tue, 25 Apr 2006 16:58
10 lines
1137 bytes
1137 bytes
"JD" <nospam@nospam.com> wrote in message news:444e08a0$1@newsgroups.borland.com... > Are you aware of any bugs with the underlying MS ListView? In what regards? Gambit
Re: WM_MOUSEMOVE
Author: JD
Date: Thu, 27 Apr 2006 12:30
Date: Thu, 27 Apr 2006 12:30
37 lines
2307 bytes
2307 bytes
"Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> wrote:
>
>> Are you aware of any bugs with the underlying MS ListView?
>
>In what regards?
Any in general but I asked because of this:
http://tinyurl.com/zyjue
Some one was using a sample by Damon Chandler that pre-dated
XP and it exposed a problem when the ListView was themed. I
was able to determine that when theming was enabled, the OS
was sending WM_NOTIFY messages that it didn't send when
theming was not enabled.
When ever the code member of the LPNMHDR structure that
accompanies the WM_NOTIFY message was 0xFFFFFDEE, it caused
the control to generate a superfluous OnCustomDraw event.
I searched msdn to try to determine what was happening and
what 0xFFFFFDEE is intended for but came up empty so my
suggestion to the OP was that my best guess was that it
was ok to just swallow that message.
This leads me to believe that the underlying ListView has not
been brought up to date with the advent of XP or perhaps it's
a bug with the control. In this particular case, since I'm
doing all of the drawing, I can disable theming for the control
but where there's one bug, there's sure to be more and I just
don't want to run into a wall later.
I also don't want to be painting and repainting when it isn't
needed which is what the above was causing.
~ JD
Re: WM_MOUSEMOVE
Author: Remy Lebeau (TeamB)
Date: Thu, 27 Apr 2006 17:26
Date: Thu, 27 Apr 2006 17:26
15 lines
1408 bytes
1408 bytes
"JD" <nospam@nospam.com> wrote in message news:4450b969$1@newsgroups.borland.com... > When ever the code member of the LPNMHDR structure that > accompanies the WM_NOTIFY message was 0xFFFFFDEE, > it caused the control to generate a superfluous OnCustomDraw event. 0xFFFFFDEE is TTN_GETDISPINFOW: http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/tooltip/notifications/ttn_getdispinfo.asp Gambit
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads