CListCtrl class override and OnTimer - c++

I'm not sure if I'm doing something undocumented. I created my own class derived from CListCtrl and then overrode the OnTimer handler in it:
void CListCtrl2::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
switch(nIDEvent)
{
case MY_TIMER_ID:
{
//Do my processing
doMyProcessing();
}
break;
default:
{
//Default
CListCtrl::OnTimer(nIDEvent);
}
break;
}
}
But what seems strange to me is that this OnTimer() routine is called with timer IDs that are not mine. For instance, just from a quick debugger checkpoint research it turns out that my default handler is called with nIDEvent set to 45 and 43.
Are there some timer IDs that are reserved that I should avoid using myself?

From the CListCtrl documentation we see this text:
Also see:
Knowledge Base article Q200054: PRB: OnTimer() Is Not Called Repeatedly for a List Control
And from that article, some pertinent excerpts:
If you call the SetTimer function to send periodic WM_TIMER messages
to a list control, you may find that the WM_TIMER message handler (the
OnTimer function) for a list control is called only twice.
....
The list control uses the timer for editing labels, and for scrolling.
When you handle the timer message, if the timer ID is your own timer,
don't call the default handler (CListCtrl::OnTimer).
So, this confirms what you observe. The list control uses the timer. I can find no documentation for the specific IDs that are used. I guess that Microsoft would not wish to commit to documenting the specific IDs that were used. They would regard the control's implementation as private and would wish to retain the option of using more timer IDs in future versions. But as IInspectable points out, they could have done that by reserving a range of IDs.
My recommendation is to regard the list control's timer as out of bounds, and reserved for use by the control. For your derived class, use a different timer. Create a message only window and use it to receive timer events. You can subclass CWnd to achieve this.

Related

How to determine which sibling receieves the event?

A QWidget Class is a parent of multiple QWidget siblings which overlap. When implementing the mousePressEvent just the most recent constructed child is recieving the event.
Is there a way that all siblings get the event?
Or even better a way to set which child is expected to be recieving it?
p.s. I'm assuming this is clear enough without providing sourcecode, especially since the minimal example would be quiet big anyway. If some one expects the code to be required anyway, leave a comment and I'll add it.
You might want to use QEvent::ignore() function to mark an event as ignored in the widget. Doing so you will propagate it to the parent widget. According to Qt docs on QEvent::ignore() function:
Clears the accept flag parameter of the event object, the equivalent
of calling setAccepted(false). Clearing the accept parameter indicates
that the event receiver does not want the event. Unwanted events might
be propagated to the parent widget.
You should generate new event in callback method of each sibling class.
void QWidgetChild::mousePressEvent(QMouseEvent *event)
{
// Act
// Pass to parent
QWidget::mousePressEvent(event);
// Generate new event for objects of sibling classes
// How?
}
See postEvent documentation.

calling Beginwaitcursor function from worker thread in MFC

Can someone help me in understanding the worker threads in VC++(MFC)?
Following is my workerthread function
UINT ThreadFunc(LPVOID pParam)
{
// some initialization... etc..
AfxGetApp()->BeginWaitCursor();
...
..
/// some operations
AfxGetApp()->End WaitCursor();
}
Is it okay to call WaitCursor() functions from a worker thread?
The documentation available for BeginWaitCursor and EndWaitCursor make no mention of issues related to threading.
The one thing that is mentioned,
The actions of BeginWaitCursor are not always effective outside of a single message handler as other actions, such as OnSetCursor handling, could change the cursor.
Other threads can change the cursor as well while your worker thread is working.
Also you need to consider the actions of the CWnd message handler OnSetCursor() which handles the WM_SETCURSOR message if the ON_WM_SETCURSOR() macro is added to the message map for a CWnd derived class. See Prevent MFC application to change cursor back to default icon

ON_NOTIFY not working in my dialog when I have ON_NOTIFY_REFLECT defined by the control

In my CTreeCtrl derived class, I am acting on TVN_ITEMEXPANDED:
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, &OnTVNItemExpanded)
In the control's parent dialog, I also want to act upon the same notification, TVN_ITEMEXPANDED,
ON_NOTIFY(TVN_ITEMEXPANDED, IDC_ELEMENT_TREE, &OnTVNItemExpanded)
However, only the control class's OnTVNItemExpanded method is getting called, never my dialog's. I am using both breakpoints and seeing the desired behavior (or lack of desired behavior) in both methods to verify that only the control class's method is being called, not my dialog's method.
BUT, if I comment out the ON_NOTIFY_REFLECT from my CTreeCtrl-derived BEGIN_MESSAGE_MAP, then my dialog's method gets called!?!
Why can't the notification go both to my control and to my dialog?!?
ON_NOTIFY_REFLECT overrides ON_NOTIFY, but you can use ON_NOTIFY_REFLECT_EX instead which lets your callback decide if the message should go through to the parent or not.
See Message Reflection for Windows Controls for a more detailed explanation:
If, in your parent window class, you supply a handler for a specific
WM_NOTIFY message or a range of WM_NOTIFY messages, your handler will
be called only if the child control sending those messages does not
have a reflected message handler through ON_NOTIFY_REFLECT(). If you
use ON_NOTIFY_REFLECT_EX() in your message map, your message handler
may or may not allow the parent window to handle the message. If the
handler returns FALSE, the message will be handled by the parent as
well, while a call that returns TRUE does not allow the parent to
handle it. Note that the reflected message is handled before the
notification message.

track events in Qt

I need to get the list of all events fired in a Qt Widget ( Qt C++) like an utility which can capture all events or some function which will be called and the event details to be passed to the function every time an event is fired.
Can somebody tell me how to do this or is there any free utility available for this purpose ?
QObject::installEventFilter is what you want. You can see all events coming into an object.
If you need to see all events for everything, you can install event filter on QApplication, see documentation to QCoreApplication::notify:
Installing an event filter on QCoreApplication::instance(). Such an
event filter is able to process all events for all widgets, so it's
just as powerful as reimplementing notify(); furthermore, it's
possible to have more than one application-global event filter. Global
event filters even see mouse events for disabled widgets. Note that
application event filters are only called for objects that live in the
main thread.
If you make a class derived from QWidget (let's call it RecordingWidget) you can reimplement it's event() function to record in whatever manner you'd like (maybe keep a log in a static member of RecordingWidget) and then continue to pass the event to QWidget's default event function:
bool RecordingWidget::event(QEvent *event)
{
// Record stuff
...
// Send the event through QWidget's default event implementation
return QWidget::event(event);
}

Is there any function called after the OnInitDialog function in MFC?

I want to create a thread after the creation of a dialog box in MFC. Is there any function that Windows has provided and is automatically called after OnInitDialog so that I can create my thread inside it?
You can simply create your thread in the OnInitDialog function. There's no reason to overcomplicate things by going and searching for a different function, or splitting your initialization code up in two pieces. (There also isn't any such function, because there's no corresponding Windows message that is sent.)
If you want to get your dialog box on the screen before you create the thread, you can just show it manually using the ShowWindow function. For example:
ShowWindow(SW_SHOW);
RedrawWindow();
Also see this post by Raymond Chen: Waiting until the dialog box is displayed before doing something
OnInitDialog() is the main function called upon initialization (in reaction to WM_CREATE).
Why can't you create your thread in there?
I have changed the thread priority to below normal and when the thread executes for the first time I set the thread to normal priory. This works fine. Thanks for your response.
After many years of feeling unsatisifed with the OnTimer solution to draw first view graphics in an MFC dialog app (a favorite playground), this seemed like a nice simple solution:-
Add a WM_HSCROLL handler with class wizard.
At the end of OnInitDialog post a hscroll message with a NULL LPARAM
In handler detect the NULL, draw graphics.
a timer meant that the app was alive for some time before graphics happened, and apparently hscroll is prioritized to happen just after the WM_PAINT message which would erase a picture element to its blank state, deleting anything that was drawn during initdialog.
BOOL CSpecDlg::OnInitDialog()
{
...
PostMessage(WM_HSCROLL,0, (LPARAM)NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
void CSpecDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
if (pScrollBar==NULL)
{
plot();
}
CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}