BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

WM_MOUSEMOVE

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Native API)
View previous topic :: View next topic  
Author Message
JD
Guest





PostPosted: Sat Apr 22, 2006 11:03 am    Post subject: WM_MOUSEMOVE Reply with quote



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
Back to top
JD
Guest





PostPosted: Sat Apr 22, 2006 12:03 pm    Post subject: Re: WM_MOUSEMOVE Reply with quote



"JD" <nospam (AT) nospam (DOT) com> wrote:
Quote:

[...] (I think) with WM_MOUSEMOVE.

I should have been looking for is WM_SETCURSOR.

~ JD
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Mon Apr 24, 2006 8:03 pm    Post subject: Re: WM_MOUSEMOVE Reply with quote



"JD" <nospam (AT) nospam (DOT) com> wrote in message
news:444a0026$1 (AT) newsgroups (DOT) borland.com...

Quote:
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
Back to top
JD
Guest





PostPosted: Tue Apr 25, 2006 12:03 pm    Post subject: Re: WM_MOUSEMOVE Reply with quote

"Remy Lebeau \(TeamB\)" <no.spam (AT) no (DOT) spam.com> wrote:
Quote:

[...] 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
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue Apr 25, 2006 6:03 pm    Post subject: Re: WM_MOUSEMOVE Reply with quote

"JD" <nospam (AT) nospam (DOT) com> wrote in message
news:444e08a0$1 (AT) newsgroups (DOT) borland.com...

Quote:
Are you aware of any bugs with the underlying MS ListView?

In what regards?


Gambit
Back to top
JD
Guest





PostPosted: Thu Apr 27, 2006 1:03 pm    Post subject: Re: WM_MOUSEMOVE Reply with quote

"Remy Lebeau \(TeamB\)" <no.spam (AT) no (DOT) spam.com> wrote:
Quote:

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
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Apr 27, 2006 6:03 pm    Post subject: Re: WM_MOUSEMOVE Reply with quote

"JD" <nospam (AT) nospam (DOT) com> wrote in message
news:4450b969$1 (AT) newsgroups (DOT) borland.com...

Quote:
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
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Native API) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.