Managing PushButton notifications under MFC
-
Hello I have the following question. I am new at MFC (I am using it with VC ++ 6.0). I am trying to create a very simple window with a PushButton on it, supposed to activate a messagebox whenever it's clicked. The wizard set the application with a MainFrame class, a View derived class, a Doc derived class (it's a SDI) and the usual App class. On my behalf I added a simple CButton derived class. This class has a constructor which receives the button's coordinates, calls the base constructor CButton () and then the Create () method on those coordinates. I instantiate the button derived object on the InitInstance() method of the App derived class. This object is a heap object , so I first declare a pointer and then call the contructor with some coordinates. The pushbutton appears regularly, but when it comes to managing the BN_CLICKED event,things begin to get confusing. I added the ON_BN_CLICKED () macro to the parent window's message map (which is the View class object), as MSDN suggests, and gave it my personal message handler's overload. Well it seems that the BN_CLICKED event is never triggered : all I can detect is WM_LBUTTONDOWN which I can manage, but the problem is, this event is triggered whenever I click on the window, no matter if I click on the button or not. My question is : why does MSDN state that BN_CLICKED is triggered when a push button is clicked ? What can I do to get that event triggered and possibly managed ? To avoid misunderstandings, I want to make it clear that I am NOT using a pushbutton in a Dialog , but right in a main window. Thank you
-
Hello I have the following question. I am new at MFC (I am using it with VC ++ 6.0). I am trying to create a very simple window with a PushButton on it, supposed to activate a messagebox whenever it's clicked. The wizard set the application with a MainFrame class, a View derived class, a Doc derived class (it's a SDI) and the usual App class. On my behalf I added a simple CButton derived class. This class has a constructor which receives the button's coordinates, calls the base constructor CButton () and then the Create () method on those coordinates. I instantiate the button derived object on the InitInstance() method of the App derived class. This object is a heap object , so I first declare a pointer and then call the contructor with some coordinates. The pushbutton appears regularly, but when it comes to managing the BN_CLICKED event,things begin to get confusing. I added the ON_BN_CLICKED () macro to the parent window's message map (which is the View class object), as MSDN suggests, and gave it my personal message handler's overload. Well it seems that the BN_CLICKED event is never triggered : all I can detect is WM_LBUTTONDOWN which I can manage, but the problem is, this event is triggered whenever I click on the window, no matter if I click on the button or not. My question is : why does MSDN state that BN_CLICKED is triggered when a push button is clicked ? What can I do to get that event triggered and possibly managed ? To avoid misunderstandings, I want to make it clear that I am NOT using a pushbutton in a Dialog , but right in a main window. Thank you
-
Hello I have the following question. I am new at MFC (I am using it with VC ++ 6.0). I am trying to create a very simple window with a PushButton on it, supposed to activate a messagebox whenever it's clicked. The wizard set the application with a MainFrame class, a View derived class, a Doc derived class (it's a SDI) and the usual App class. On my behalf I added a simple CButton derived class. This class has a constructor which receives the button's coordinates, calls the base constructor CButton () and then the Create () method on those coordinates. I instantiate the button derived object on the InitInstance() method of the App derived class. This object is a heap object , so I first declare a pointer and then call the contructor with some coordinates. The pushbutton appears regularly, but when it comes to managing the BN_CLICKED event,things begin to get confusing. I added the ON_BN_CLICKED () macro to the parent window's message map (which is the View class object), as MSDN suggests, and gave it my personal message handler's overload. Well it seems that the BN_CLICKED event is never triggered : all I can detect is WM_LBUTTONDOWN which I can manage, but the problem is, this event is triggered whenever I click on the window, no matter if I click on the button or not. My question is : why does MSDN state that BN_CLICKED is triggered when a push button is clicked ? What can I do to get that event triggered and possibly managed ? To avoid misunderstandings, I want to make it clear that I am NOT using a pushbutton in a Dialog , but right in a main window. Thank you
Check your PUSHBUTTON is not disabled.For a BN_CLICKED message, The parent window is notified through WM_COMMAND with control ID and handler. wParam The LOWORD contains the button's control identifier. The HIWORD specifies the notification code. lParam A handle to the button
-
Have you set the button's parent
CWnd
to the same window that has the message map?The best things in life are not things.
Yes Richard. Though it wasn't clear at the beginning which one it was, since i had no pointer to the single objects , I figured out it was the MainFrame window object created by te wizard since it's the only one which seems to receive the WM_LBUTTONDOWN when I click the mouse. I don't know if it is important but, peeking the system messages with Spy++, I couldn't see any BN_CLICKED , when instead I was seeing a lot of BM_SETSTATEs .
-
Yes Richard. Though it wasn't clear at the beginning which one it was, since i had no pointer to the single objects , I figured out it was the MainFrame window object created by te wizard since it's the only one which seems to receive the WM_LBUTTONDOWN when I click the mouse. I don't know if it is important but, peeking the system messages with Spy++, I couldn't see any BN_CLICKED , when instead I was seeing a lot of BM_SETSTATEs .
You say its parent is the
MainFrame
but your message map entry is in your view; I suspect this may be wrong. Also note thatBN_CLICKED
[^] is a notification not a message, and gets sent to your application via aWM_COMMAND
message.The best things in life are not things.
-
Check your PUSHBUTTON is not disabled.For a BN_CLICKED message, The parent window is notified through WM_COMMAND with control ID and handler. wParam The LOWORD contains the button's control identifier. The HIWORD specifies the notification code. lParam A handle to the button
Following MSDN's instructions, I put the ON_BN_CLICKED() macro in the message map , like this: ON_BN_CLICKED (IDC_MYBUTTON, OnClicked) where IDC_MYBUTTON is the ID I give to the button when I create it, and OnClicked is the message handler I defined for the event, in the same file as the message map. I tried to put this kind of event management everywhere in the project, but it never worked . When you say "disabled" , what do you mean ? to be disabled,a push button must be created that way, right ? Anyway if it were disabled, it wouldn't send the WM_LBUTTONDOWN message I guess, right ?
modified on Wednesday, July 27, 2011 6:03 AM
-
You say its parent is the
MainFrame
but your message map entry is in your view; I suspect this may be wrong. Also note thatBN_CLICKED
[^] is a notification not a message, and gets sent to your application via aWM_COMMAND
message.The best things in life are not things.
This is something I am confused about : I see the only message I get is intercepted by the view object /message map but, inquiring the start of the application with the debugger, I came to the comclusion that the only window pointer that the wizard makes available in the application source is the MainFrame's one : I maybe wrong on this but I suspect it creates the CThread object for the current thread, then derives a CApp object from the Cthread class , and then it assignes the m_pMainWnd pointer of the CThread object to the CApp object , then assignes this one to the MainFrame's object.... following all thisnon the debugger is not the best so I could have misunderstod many things .... I couldn't find any other window pointers related to the Doc, View , and user App objects.
-
This is something I am confused about : I see the only message I get is intercepted by the view object /message map but, inquiring the start of the application with the debugger, I came to the comclusion that the only window pointer that the wizard makes available in the application source is the MainFrame's one : I maybe wrong on this but I suspect it creates the CThread object for the current thread, then derives a CApp object from the Cthread class , and then it assignes the m_pMainWnd pointer of the CThread object to the CApp object , then assignes this one to the MainFrame's object.... following all thisnon the debugger is not the best so I could have misunderstod many things .... I couldn't find any other window pointers related to the Doc, View , and user App objects.
I suspect your problem may lie with where you created your button. From your earlier description of where you want to capture the button click, I think your button should be a child of (and created in) your
CView
class. This is one of the issues with using a Wizard, it is not always as flexible as you need in special circumstances. You may also like to rethink the design of your application, particularly with regard to why you want this button. Could it be replaced by a simple toolbar button?The best things in life are not things.
-
I suspect your problem may lie with where you created your button. From your earlier description of where you want to capture the button click, I think your button should be a child of (and created in) your
CView
class. This is one of the issues with using a Wizard, it is not always as flexible as you need in special circumstances. You may also like to rethink the design of your application, particularly with regard to why you want this button. Could it be replaced by a simple toolbar button?The best things in life are not things.
This idea slightly surfaced in my mind, but I had rapidly dismissed it on the basis of what I had understood (if well understood) about MCF : I was convinced that the only source code I should put my hands on was the xxxApp class , but ... is it right ? Maybe not ..... Anyway, I'll try to test this : I should redesign my application creating the Push Button in the OnDraw () message handler of the View class, I suppose : right ? Well you know , this "application" I just made out of curiosity , to skill myself , so I should try to solve as many problems as I can without totally rethinking the architecture, which is already so simple. Thank you
-
This idea slightly surfaced in my mind, but I had rapidly dismissed it on the basis of what I had understood (if well understood) about MCF : I was convinced that the only source code I should put my hands on was the xxxApp class , but ... is it right ? Maybe not ..... Anyway, I'll try to test this : I should redesign my application creating the Push Button in the OnDraw () message handler of the View class, I suppose : right ? Well you know , this "application" I just made out of curiosity , to skill myself , so I should try to solve as many problems as I can without totally rethinking the architecture, which is already so simple. Thank you
tiwal wrote:
I was convinced that the only source code I should put my hands on was the xxxApp class
No, that's probably the one class that you won't need to change very much. The majority of actual work in your application will be done, first in the
CDocument
class, which handles the data that you are to process, and second in yourCView
class where your data will be presented to the user. Outside these two classes there is only a small bit of administration to link things together.tiwal wrote:
creating the Push Button in the OnDraw () message handler of the View class
I don't think so! The
OnDraw()
handler should only be concerned with rendering your data onto the view for the user to read. If you need to have a button on your view then you should make it a member of your view class and create it in theOnCreate()
function of the view class. It is probably worth looking for some introductory MFC articles to get a feel for how these classes fit together, and what each should do during the life of the application.The best things in life are not things.
-
This idea slightly surfaced in my mind, but I had rapidly dismissed it on the basis of what I had understood (if well understood) about MCF : I was convinced that the only source code I should put my hands on was the xxxApp class , but ... is it right ? Maybe not ..... Anyway, I'll try to test this : I should redesign my application creating the Push Button in the OnDraw () message handler of the View class, I suppose : right ? Well you know , this "application" I just made out of curiosity , to skill myself , so I should try to solve as many problems as I can without totally rethinking the architecture, which is already so simple. Thank you
You were right Richard ... now it works perfectly !! So my mistake was in thinking that all I should modify was the CApp derived class. Thank you for your precious support, you really dragged me out of a mud pond ..... :thumbsup::thumbsup::thumbsup: greetings and regards, Leo
-
You were right Richard ... now it works perfectly !! So my mistake was in thinking that all I should modify was the CApp derived class. Thank you for your precious support, you really dragged me out of a mud pond ..... :thumbsup::thumbsup::thumbsup: greetings and regards, Leo