|
From MSDN: "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."
Solution: use ON_NOTIFY_REFLECT_EX() .
|
|
|
|
|
Thank you very much . Now it goes ! Plus , I learn something here !!!
modified on Saturday, March 5, 2011 12:53 PM
|
|
|
|
|
Here is my drama. I have created a class, which is responsible for creating main application window, applying vista glass effect to it and setting background image - all in one. So now i have, kind of, 2 window procedures - one is inside a class, which is responsible for painting candy look vista transparency and bkg pic, and one is outside the class, which is responsible for command events and such, but also for painting some additional controls. So currently i have 2 different WM_PAINT's. The problem is - i cannot paint anything in 2'nd WM_PAINT (which is outside the class) while i can paint everything inside a class. And there is no difference if i export a handle to device context from class to 2'nd wndproc - i just cannot paint anything outside class. Here are steps (in code):
static LRESULT CALLBACK mWindow::WndProc(IN HWND hwnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
mWindow *self;
if (uMsg == WM_NCCREATE) {
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
self = (mWindow *)lpcs->lpCreateParams;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)self);
}
else
{
self = (mWindow *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
if (self)
{
return self->InternalWndProc(hwnd, uMsg, wParam, lParam);
}
else
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
__w64 long __stdcall InternalWndProc(IN HWND hWnd,
IN unsigned int msg,
IN __w64 unsigned int wParam,
IN __w64 long lParam)
{
switch(msg)
{
case wm_paint:
OnPaint();
break;
default:
return _outer_procedure(hWnd, msg, wParam, lParam);
}
return _outer_procedure(hWnd, msg, wParam, lParam);
}
__w64 long __stdcall WndProc(IN HWND hWnd,
IN unsigned int msg,
IN __w64 unsigned int wParam,
IN __w64 long lParam)
{
switch(msg)
{
case WM_PAINT:
{
Gdiplus::Graphics graphics((HDC)AppWindow->operator HDC());
Gdiplus::Pen pen(Gdiplus::Color::Black);
graphics.DrawLine(&pen, 100, 100, 200, 100);
}
break;
}
}
So, what is going on here? Maybe after 1'st WM_PAINT handle to device context becomes invalid and not reusable? I just dont know. Thanks for any help.
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
What is
csrss wrote: case wm_paint:
?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Thats a quick typing, WM_PAINT ofcourse. Basically after some time i came with an idea of passing separate functions to a class, like: OnPaint, OnDestroy, etc Seems like my window class will grow to 10000 lines xD
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
If you are using CPaintDC in your first OnPaint() function like below;
void CSomeClass::OnPaint()
{
CPaintDC dc(this);
...
}
EndPaint() is called automatically in CPaintDC's destructor while going out of scope. EndPaint() marks the end of painting. If so, you can try using GetDC() to get device context in second.
I think, the best is that all painting stuff should be between ::BeginPaint() and ::EndPaint() calls within a WM_PAINT message.
|
|
|
|
|
No no, i am not using MFC, - this OnPaint() thing is my small custom function (like other small funcs), which i am passing to a class as callbacks, well, passing now, because like you've said, all stuff totally goes between BeginPaint and EndPaint in only 1st WM_PAINT. In fact, there should be no 2nd client paint handler, - that was my little experiment , which proved that a coder should stick to the rules
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
csrss wrote: Maybe after 1'st WM_PAINT handle to device context becomes invalid
Impossible to tell without seeing what is going on inside your OnPaint() function. Do you call BeginPaint() and EndPaint() correctly, and at the appropriate times? In your second paint handler you have not checked the return status of your call to graphics.DrawLine() which may give some useful information. Did you initialise GDI+ correctly at the start of your program?
I must get a clever new signature for 2011.
|
|
|
|
|
Yup, GDI+ was initialized, actually in my OnPaint() it was doing same (after painting bkg image) - just drawing a line (thats just a testing functionality). While it could do so in class it couldnt outside the class. But thats a good point, i did not check the status of drawline(). However, code now is completely reorganized to do all painting in class so there is no quick way to rollback to its initial state and do a checking so... Thanks anyway
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
Hello,
I am currently getting to grips with MFC, VC++, VS2010 and threading. In particular I am trying to start a thread from a CMainFrame object, then post a windows message from the thread back to he CMainFrame object such that a messagebox can be displayed indicating the progress of the thread.
In this example the uses starts the thread from a drop-down menu item (CreateWorkerThread function is called) the thread code executes and sends a single windows message towards the end of the thread. The problem I have is that CMainFrame doesn't seem to respond to the message unless the function that starts the thread uses a ::WaitForSingleObject() call. Why do I need to effectively pause the execution of the function creating the thread?
Mayby naively, I assumed the following actions:
-User selects Menu item
-CreateWorkerThread() is called
-Thread executes in parallel with the remains of CreateWorkerThread()
-Worker thread generates a windows message (using ::PostMessage())
-By now CreateWorkerThread() would have completed.
-CMainFrame Message map processes Worker Thread' message 'WM_THREAD1MSG'
-Messagebox created and presented to user.
void CMainFrame::CreateWorkerThread(void)
{
HWND hWnd = GetSafeHwnd();
if (hWnd == NULL)
{
TRACE0("Window pointer is invalid!");
}
hWnd = GetSafeHwnd();
pThread1 = AfxBeginThread(mcProc, static_cast<LPVOID>(&hWnd), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
pThread1 ->ResumeThread();
DWORD ThreadExitCodeValue = 0;
LPDWORD pDWord = NULL;
pDWord = &ThreadExitCodeValue;
HANDLE pThreadHandle = pThread1->m_hThread;
::WaitForSingleObject(pThreadHandle,INFINITE);
}
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
ON_WM_CREATE()
ON_MESSAGE(WM_THREAD1MSG, Respond2ThreadMsg)
ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
ON_COMMAND(ID_GCCODEDVMT_TESTCOMMAND, TestCommand)
ON_COMMAND(ID_GCCODEDVMT_CREATEWORKERTHREAD, CreateWorkerThread)
ON_COMMAND(ID_GCCODEDVMT_TERMINATEWORKERTHREAD, TerminateWorkerThread)
ON_WM_SETTINGCHANGE()
END_MESSAGE_MAP()
UINT mcProc(LPVOID param)
{
CString TempString;
CString TempString2;
int i = 0;
int y = 0;
HWND *pHandle = static_cast<HWND*>(param);
for (i=0; i<10; i++)
{
TempString.Format(_T("index counter: %d, \n"), i);
TempString2 = _T("Thread 1 Started... ");
TempString2 += TempString;
TRACE(TempString2);
::Sleep(1000);
}
y = ::PostMessage(*pHandle, WM_THREAD1MSG, 0, 0);
Sleep(1000);
return 0;
}
LRESULT CMainFrame::Respond2ThreadMsg(WPARAM xParam, LPARAM lParam)
{
AfxMessageBox(_T("Thread message received"));
TRACE(_T("Thread message received /n"));
return 0;
}
Opinions greatfully received.
regards
Geoff
|
|
|
|
|
You're passing the address of a temporary variable to the thread: when CreateWorkerThread exits, hWnd goes out of scope.
BTW: There is really no need to pass a pointer to the HWND , just pass the HWND value.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Many thanks for feedback
Since posting this message I realised that I have been using the WINAPI PostMessage() function call rather than the MFC wrapper CWnd::PostMessage(). Which is the preferred method?
regards
Geoff
|
|
|
|
|
CWnd::PostMessage internally calls win32 ::PostMessage .
I'll use CWnd::PostMessage , if I've CWnd object(no need to wrap window handle, specially to use this version), and ::PostMessage , if I've window handle.
|
|
|
|
|
prasad_som wrote: I'll use CWnd::PostMessage , if I've CWnd object(no need to wrap window handle, specially to use this version), and ::PostMessage , if I've window handle.
So you'll use both at the same time when you have a CWnd object...
Pardon the silly humour...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
GC104 wrote: I have been using the WINAPI PostMessage() function call rather than the MFC wrapper CWnd::PostMessage()
You have to use the Windows API function. Worker threads aren't CWnd .
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
You already got answer in earlier post. If you want to pass pointer to handle, use address of m_hHandle member variable, which is handle of CMainFrame. No need to call GetSafeHwnd.
|
|
|
|
|
hello guys...I made this small console app inwhich I can get the difference (duration) between two times. I then store them into database as string. But the problem is that sometimes it shows some weird difference which I am unable to trace. Here is what I have
SYSTEMTIME t,t2,t3;
GetSystemTime(&t);
GetSystemTime(&t2);
t3.wHour = t2.wHour - t.wHour;
t3.wMinute = t2.wMinute - t.wMinute;
t3.wSecond = t2.wSecond - t.wSecond;
GetMyDateTime2(t,t2,t3);
But here is one of the durations that I got from this calculation
2 3/3/2011 21:57:57 3/3/2011 21:58:3 0:1:65482(duration) D:\Recordings\SecondRec.wav
what can be the problem?? thnx
modified on Friday, March 4, 2011 5:08 AM
|
|
|
|
|
The problem is your calculations are wrong (do you remember 'carry'?) and the SYSTEMTIME fields are 16 bit WORDS .
Try
WORD wCarry;
if (t2.wSecond >= t1.wSecond )
{
wCarry = 0;
t3.wSecond = t2.wSecond - t1.wSecond;
}
else
{
wCarry = 1;
t3.wSecond = 60 + t2.wSecond - t1.wSecond;
}
if (t2.wMinute >= t1.wMinute + wCarry)
{
wCarry = 0;
t3.wMinute = t2.wMinute - t1.wMinute;
}
else
{
wCarry = 1;
t3.wMinute = 60 + t2.wMinute - t1.wMinute;
}
if (t2.wHour >= t1.wHour + wCarry)
{
t3.wHour = t2.wHour - t1.wHour;
}
else
{
}
Please note the above code would have troubles on button clicks crossing the date boundary...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
If you can use CTime and CTimeSpan MFC classes, no need to bother about calculations.
|
|
|
|
|
overloaded Name wrote: hello guys...I made this small console app inwhich I can get the difference
(duration) between two times.
You might also check out difftime() .
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
|
|
|
|
|
By far, the simplest way is GetSystemTimeAsFileTime[^]. This returns a FILETIME[^] struct which contians 2 DWORDs which you can then drop directly into a ULARGE_INTEGER[^].
FILETIME ftStart, ftEnd;
GetSystemTimeAsFileTime(&ftStart);
GetSystemTimeAsFileTime(&ftEnd);
ULARGE_INTEGER liStart = { ftStart.dwLowDateTime, ftStart.dwHighDateTime };
ULARGE_INTEGER liEnd = { ftEnd.dwLowDateTime, ftStart.dwEndDateTime };
printf("Duration: %I64u ms\n", (liEnd - liStart) / (10 * 1000));
or, if you dont mind using casts since ULARGE_INTEGER and FILETIME have the same structure:
ULARGE_INTEGER liStart, liEnd;
GetSystemTimeAsFileTime((FILETIME *)&liStart);
GetSystemTimeAsFileTime((FILETIME *)&liEnd);
printf("Duration: %I64u ms\n", (liEnd - liStart) / (10 * 1000));
|
|
|
|
|
Hi all,
I have made a Dialog based application, on that dialog I have 3 option buttons and one push button. On click of option buttons a variable called flag value is being set to 1,2 or 3 respectively. my problem is that when i click on push button i hide it and after that flow of control automatically transfers to any option button click code and it changes the flag value....
my stop button and option button is not having any relation with each other....
I have tried it in new application it works fine... but i want to correct it in my exsisting application...
How can i resolve it
Thanks in advance
|
|
|
|
|
VCProgrammer wrote: I have made a Dialog based application, on that dialog I have 3 option buttons...
Do you mean radio button?
VCProgrammer wrote: my stop button and option button is not having any relation with each
other....
Which means what?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Some people are making such thorough preparation for rainy days that they aren't enjoying today's sunshine." - William Feather
|
|
|
|
|
|
Check if you are duplicating button ids in any way. or using wrong message mappings.
|
|
|
|
|