| Home Forum RSS PGP Alerts Links (D) |
|
|
|
|
Constructing hidden windows in ATL Comment on this articleGetting timer messages into an ATL object isn't all that evident. If you create a full control and it remains invisible in runtime, it has no windows handle, so you can't use the classical ::SetTimer(hWnd,...) to get the timer messages. The trick is to create another ATL window object that does absolutely nothing but create a window and get these messages. Then have the timer message handler call whatever method you want in your "real" ATL object. The extra ATL window class looks like the following. I place it in the same file as the main ATL class, but before it, adding a forward class declaration for the main class, of course. In the constructor it takes a pointer to the ATL object that needs timer ticks.
// fullctrl.h
class CWinHidden :
public CWindowImpl<CWinHidden, CWindow, CNullTraits>
{
BEGIN_MSG_MAP(CWinHidden)
MESSAGE_HANDLER(WM_TIMER, OnTimer)
END_MSG_MAP()
public:
CWinHidden(Cfullctrl* pFullCtrl) : m_pFullCtrl(pFullCtrl) {};
public:
LRESULT OnTimer(UINT, WPARAM, LPARAM, BOOL&);
private:
Cfullctrl* m_pFullCtrl;
};
The OnTimer handler does nothing but call the "real" ATL object. In this case I call the OnTimer() handler, but actually it could be anything you like. // fullctrl.cpp
LRESULT CWinHidden::OnTimer(UINT uMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
m_pFullCtrl->OnTimer(uMsg, wParam, lParam, bHandled);
return 0;
}
Caveat: Now you have two objects running message loops here. If this is all in an STA, there should be no problems, but if you're using more advanced threading models, I can very well imagine that having the one object (CWinHidden) just call right into the other (Cfullctrl) is not entirely safe. If so, you would need to use mutexes and/or critical sections to secure things. |
| TOP |