|
I am adding a feature into my application programs which will be using shared (mapped) memory to communicate between two programs.
I made a demo1 program to test and verify the class implementations. It works well.
So I started to do one of the real application program. To prevent two instances in the system, I used CreateMutex for that.
HANDLE hMutex = CreateMutex(NULL, FALSE, MUTEX_NAME);
if(hMutex) {
if(ERROR_ALREADY_EXISTS == GetLastError()) {
return FALSE;
}
}
Later during the initialization of the program, I found CreateFileMapping failed.
m_hFile = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
m_dwBufSize,
m_sMappingName);
When I removed the CreateMutex line, CreateFileMapping returned a valid handle.
Are they using the same system resource?
Maxwell Chen
|
|
|
|
|
What did CreateFileMapping fail with, call GetLastError and see what it says, maybe it helps to decypher the problem.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Code-o-mat wrote: What did CreateFileMapping fail with, call GetLastError and see what it says, maybe it helps to decypher the problem.
When CreateMutex is used in the code in CDemoApp::InitInstance , CreateFileMapping returns a NULL value. GetLastError() returns 0x00000006 (invalid handle).
When CreateMutex is NOT used in the code, CreateFileMapping returns a valid handle to the mapped memory.
Maxwell Chen
|
|
|
|
|
This is strange, i find it very unlikely that CreateMutex would affect CreateFileMapping . I have worked with a project that used quite a few mutexes for synchronization and also used file mappings to access data (not using the paging file though) and there was no trouble with working altogether.
Are you completely sure that the only difference between the two "versions" is the creation of the mutex?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Code-o-mat wrote: Are you completely sure that the only difference between the two "versions" is the creation of the mutex?
Yes! I just used // to comment out the lines.
Maxwell Chen
|
|
|
|
|
Is it possible that you specified the same name for the mutex and the file mapping object?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Code-o-mat wrote: Is it possible that you specified the same name for the mutex and the file mapping object?
I had also considered this possibility, too. So I have tried using different names for the mutex and the mapped memory individually. Not working...
Maxwell Chen
|
|
|
|
|
Try creating an unnamed mutex and see if that changes anything. I know you will need a named one but this is just for testing.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Code-o-mat wrote: Try creating an unnamed mutex and see if that changes anything. I know you will need a named one but this is just for testing.
I just tried this, and it works.
And I also tried again the mutex with name A and the mapped memory with name B. It also works now.
I think my system was getting crazy.
But thank you anyway.
Maxwell Chen
|
|
|
|
|
Also, the documentation[^] of CreateFileMapping states this:
"If lpName matches the name of an existing event, semaphore, mutex, waitable timer, or job object, the function fails, and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace.", this should be a name-collision issue. Just to test this, try explicitly specifying "appleappleapple" for your mutex and "pearpearpear" for your mapping object, i mean, directly where you call the creation methods, not using a macro or any member variable.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I've given this a 5, not 'cause of the original answer but because of the way code-o-mat followed the problem through to it's solution. Class act!
Cheers,
Ash
|
|
|
|
|
Thanks.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
The APIs are not related in anyway.
Just to be sure I tried to run the piece of code and it works perfectly.
So the only thing relating both the APIs in the code above is the name.
By giving the same name for both the mutex and the mapping, I'm able to reproduce the error with GetLastError returning the error code 6.
|
|
|
|
|
Maxwell Chen wrote: if(hMutex) {
shouldn't that be if(!hMutex) { ?
|
|
|
|
|
Luc Pattyn wrote: shouldn't that be if(!hMutex) { ?
Nope, my original code snippet as the below is correct.
HANDLE hMutex = CreateMutex(NULL, FALSE, MUTEX_NAME);
if(hMutex) {
if(ERROR_ALREADY_EXISTS == GetLastError()) {
return FALSE;
}
}
Maxwell Chen
|
|
|
|
|
My mistake. This is one of the exceptional cases where calling GetLastError makes sense even when the function succeeded.
|
|
|
|
|
Maxwell Chen
|
|
|
|
|
What happens after you return FALSE ?
Otherwise, I think you just leaked a system object handle.
Your program should technically close the mutex handle if you are not going to use it.
|
|
|
|
|
Current, I have a parent CWnd, which is displaying many other child CWnds. All my message handling job are being done in parent CWnd, as I do not have access to child CWnds' code.
I wish to know which child CWnds is being clicked.
I can detect the right click
afx_msg void OnContextMenu(
CWnd* pWnd,
CPoint pos
);
pWnd will be the clicked child window.
However, how about left click? I know I can get the mouse coordinate, and perform some calculation accordingly to iterate through see which child CWnds falll into the point. However, I just don't want to go through all this. I which I can have something like.
CWnd* childWind = mouseEvent.getParent();
|
|
|
|
|
for simple child controls, override parent CWnd's PreTranslateMessage().
BOOL CMyWnd::PreTranslateMessage(MSG* pMsg)
{
BOOL b = CDialog::PreTranslateMessage(pMsg);
if(pMsg->message == WM_LBUTTONDOWN)
{
if(pMsg->hwnd == m_edit.GetSafeHwnd())
MessageBox("Edit control);
}
return b;
}
if you need to get mouse click on edit field of combo box, or scroll bar of list box, i think you have to to subclass them.
|
|
|
|
|
Please try it :
BOOL CYourParentWnd::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
*pResult = 0;
NMHDR* pHeader = (NMHDR*) lParam;
switch (pHeader->code) {
case NM_CLICK:
{
CWnd* pcChild = CWnd::FromHandle(pHeader->hwndFrom);
}
break;
}
return FALSE;
}
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
are you sure that WM_NOTIFY will be sent to parent window by all controls on mouse click?
|
|
|
|
|
No, I am not sure for "all" controls...
...but I would test it in the author's context
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
|
If you can, please leave a contact。
I want to be a hacker, how should I do?
I do not want to engage in sabotage, just interested in the Trojan Programming.
|
|
|
|