|
Funny thing is that posting the class code here would have kept everyone scratching their head, since the guilty header wasn't even part of that code. That's why it worked fine when I pulled it into another application (which is what I did for testing).
|
|
|
|
|
I suppose it's time for posting your class code here.
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]
|
|
|
|
|
I might do that next... its not particularly complicated code, so this is a real pain in the butt
|
|
|
|
|
Can you post more details?
Steve
|
|
|
|
|
We have some code which creates a 64-bit MD5 which is not used for encryption, but as an identifier. We're adding other code that has a 128-bit MD5 and I'd like to drop the 64-bit MD5 algorithm and just convert a 128-bit hash to 64-bit for this one case. It would be nice to avoid collisions, but not a big deal if they happen.
Anyone know the best way to do this?
|
|
|
|
|
Any 64 bits of the 128 (provided you pick the same ones every time!) will do what you are trying to do. The idea of a hash like MD5 is that each bit of the hash depends on (nearly) all input bits. Make it easy by picking the leftmost 64, or the rightmost.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
|
|
|
I've used MFC within DLLs a lot, those articles just talk about the different ways of doing it. I use the "C-like" function interface with MFC dynamically linked.
|
|
|
|
|
Hi . I stock on the follow problem :
I have an CListCtrlEx , derived from CListCtrl , where I have :
afx_msg void OnHdnItemclick(NMHDR* pNMHDR, LRESULT* pResult);
and implementation :
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, CListCtrlEx::OnHdnItemclick)
...
...
void CListCtrlEx::OnHdnItemclick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* phdr = reinterpret_cast<NM_LISTVIEW*>(pNMHDR);
SortOnColumn(phdr->iSubItem, TRUE);
*pResult = 0;
}
and I need to catch LVN_COLUMNCLICK in parent window :
afx_msg void OnHdnItemclickList1(NMHDR* pNMHDR, LRESULT* pResult);
and implementation :
ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST1, OnHdnItemclickList1)
...
...
void CTestList5View::OnHdnItemclickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* phdr = reinterpret_cast<NM_LISTVIEW*>(pNMHDR);
CString sTemp;
sTemp.Format("%d",phdr->iSubItem);
TRACE("\n column %s\n",sTemp);
*pResult = 0;
}
the problem is that program don't cross through CTestList5View::OnHdnItemclickList1
.... why ? And how can I solve the problem ?
|
|
|
|
|
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]
|
|
|
|
|