|
You can't pass a pointer between apps, because an address in app 1's memory space is meaningless in app 2's memory space.
Using shared memory for this isn't a kludge; it's the proper way to share data.
|
|
|
|
|
1) Use WM_COPYDATA message to copy the string. OS will make sure it works across process boundary.
2) Use global atom table, pass atom handle.
|
|
|
|
|
The following lines are taken from 'Visual C++ 4 Unleashed":
***********************************************************
Memory-Mapped Files and Shared Memory
---------------------------------------
Earlier in this chapter, I mentioned that applications are no longer capable of communicating using global memory created with the GMEM_DDESHARE flag. Instead, they must use memory-mapped files to share memory. What are memory-mapped files?
Normally, the virtual memory mechanism enables an operating system to map nonexistent memory to a disk file, called the paging file. It is possible to look at this the other way around and see the virtual memory mechanism as a method of referring to the contents of a file, namely the paging file, through pointers as if the paging file were a memory object. In other words, the mechanism maps the contents of the paging file to memory addresses. If this can be done with the paging file, why not with other files? Memory-mapped files represent this natural extension to the virtual memory management mechanism.
You can create a file mapping by using the CreateFileMapping function. You can also use the OpenFileMapping function to enable an application to open an existing named mapping. The MapViewOfFile function maps a portion of the file to a block of virtual memory.
The special thing about memory-mapped files is that they are shared between applications. That is, if two applications open the same named file mapping, they will, in effect, create a block of shared memory.
Isn't it a bit of an overkill to be forced to use a disk file when the objective is merely to share a few bytes between two applications? Actually, it is not necessary to explicitly open and use a disk file in order to obtain a mapping in memory. Applications can submit the special handle value of 0xFFFFFFFF to CreateFileMapping in order to obtain a mapping to the system paging file itself. This, in effect, creates a block of shared memory.
Listings 13.3 and 13.4 demonstrate the use of shared memory objects for intertask communication. They implement a very simple mechanism where one program, the client, deposits a simple message (a null-terminated string) in shared memory for the other program. This other program, the server, receives the message and displays it. These programs are written for the Windows 95 or Windows NT command line. To see how they work, start two MS-DOS windows, start the server program first in one of the windows, and then start the client program in the other. The client sends its message to the server; the server, in turn, displays the message it receives and then terminates.
Listing 13.3. Intertask communication using shared memory: The server.
#include <iostream.h>
#include <windows.h>
void main(void)
{
HANDLE hmmf;
LPSTR lpMsg;
hmmf = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, 0x1000, "MMFDEMO");
if (hmmf == NULL)
{
cout << "Failed to allocated shared memory.\n";
exit(1);
}
lpMsg = (LPSTR)MapViewOfFile(hmmf, FILE_MAP_WRITE, 0, 0, 0);
if (lpMsg == NULL)
{
cout << "Failed to map shared memory.\n";
exit(1);
}
lpMsg[0] = '\0';
while (lpMsg[0] == '\0') Sleep(1000);
cout << "Message received: " << lpMsg << '\n';
UnmapViewOfFile(lpMsg);
}
Listing 13.4. Intertask communication using shared memory: The client.
#include <iostream.h>
#include <windows.h>
void main(void)
{
HANDLE hmmf;
LPSTR lpMsg;
hmmf = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, 0x1000, "MMFDEMO");
if (hmmf == NULL)
{
cout << "Failed to allocated shared memory.\n";
exit(1);
}
lpMsg = (LPSTR)MapViewOfFile(hmmf, FILE_MAP_WRITE, 0, 0, 0);
if (lpMsg == NULL)
{
cout << "Failed to map shared memory.\n";
exit(1);
}
strcpy(lpMsg, "This is my message.");
cout << "Message sent: " << lpMsg << '\n';
UnmapViewOfFile(lpMsg);
}
These two programs are nearly identical. They both start by creating a file mapping of the system paging file with the name MMFDEMO. After the mapping is successfully created, the server sets the first byte of the mapping to zero and enters a wait loop, checking once a second to see whether the first byte is nonzero. The client, in turn, deposits a message string at the same location and exits. When the server notices that the data is present, it prints the result and also exits.
Both programs can be compiled from the command line: cl mmfsrvr.cpp and cl mmfclnt.cpp.
************************************************************
You can find this book and many book on page http://kitap.selcuk.edu.tr (I think it is unavailable now, but will be operational in a few days).
Mustafa Demirhan
|
|
|
|
|
hi,
i have found another solution from the book:
***********************************************************
Shared Memory and Based Pointers
---------------------------------
A shared memory mapped file object may not necessarily appear at the same address for all processes. While shared memory objects are mapped to identical locations in the address spaces of Windows 95 processes, the same is not true in Windows NT. This can be a problem if applications want to include pointers in the shared data. One solution to this problem is to use based pointers and set them to be relative to the start of the mapping area.
Based pointers are a Microsoft-specific extension of the C/C++ language. A based pointer is declared using the __based keyword, in a fashion similar to the following:
<br />
void *vpBase;<br />
void __based(vpBase) *vpData;<br />
References through the based pointer always point to data relative to the specified base. Their utility extends beyond shared memory; based pointers can also be very useful when saving data that contains pointers to disk.
Mustafa Demirhan
|
|
|
|
|
I'm looking ways to do a variation on Doc/View that would accommodate the video editor app i'm writing. I want it to be SDI in the sense that only one document can be open at a time, but I want it to be MDI in the sense that there can be many different views opened (onto the same doc, of course) at once.
There would be a window (floating toolbar, probably) with a series of video frames and the user could double click a frame to open a full-sized window into the area where the MDI windows would normally go.
I guess this would be a SDMV (Single Doc, Multi View) app, instead of an MDI or SDI app.
Has anyone here done anything like this before?
I've looked around on this and that other code site, but didn't find anything the fit.
-c
|
|
|
|
|
I have just such a solution. Give me a week to clean up the code and make a test application showing how to use it.
|
|
|
|
|
I think you should start with an MDI application, then override ID_FILE_OPEN and ID_FILE_NEW or something like that to allow only one document. The details of how that is done is somewhat determined by how you want the file to be specified that you will allow open.
I am not entirely sure of how well that will work, but I think it could work well.
|
|
|
|
|
I seem to have a problem getting radio buttons to enable, pending the state of another button...The radio buttons, are drawn with a default style of BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED...When I send a BM_SETSTYLE message to the buttons with SendDlgItemMessage() The button does not enable. Does anyone know why this happens, and what can be done about it using only win32? If you would like to see the code, or need more information let me know...thanks in advance...
|
|
|
|
|
I just noticed a strange problem with my app. I'm not able to step into >some< of the MFC library source files while debugging. So far, the problem occurs with CWinApp and CMDIFrameWnd but does not occur with the container classes. Debugging everything else seems to be working just fine!
I've verified that I don't have any unusual settings in my debug build configuration.
Any suggestions???
|
|
|
|
|
I ran across the following article on MSDN:
Article ID: Q121556
There is a section titled "Missed breakpoints when more than one copy of DLL on your hard disk" that made me remember that I had two copies of the debug MFC dll's on my system.
I removed the duplicate files and all is well.
I guess the OS was loading the duplicate DLL's, which were in the same dir as my .exe, and the IDE was waiting for the WINNT\system32 MFC files to run. The system MFC DLL's would of course never load because the duplicates were found first and the IDE's debug information probably only targets the system DLL's.
|
|
|
|
|
I added new browser control to my project and now i'm getting this error, regardless if I remove it now.
error C2011: 'CWebBrowser2' : 'class' type redefinition
\webbrowser2.h(9) : error C2011: 'CWebBrowser2' : 'class' type redefinition
\ProfileView.cpp(537) : error C2039: 'ControlDownload' : is not a member of 'CWebBrowser2'
\webbrowser2.h(9) : see declaration of 'CWebBrowser2'
|
|
|
|
|
Hi all,
i am looking for ppl who are experts in Rational Rose Application, specially who know how to work with Rose Automation...
any1 who can refer me even to Rational Rose forum will be appreciated.
please email me at
ynir@legacy2web.com
or at
n_yaron@netvision.net.il
tnx a lot
|
|
|
|
|
I want to use API for displaying the Choose Folder Dialog as we find in the
installation of s/w packages. It should be possible to select the drive from a drivelist. On selection the directories in that drive will be displayed in a directory list and the selected directory should be visible in a text box
Note My intension is not to use The function SHBrowseForFolder
Thanks in advance
santhosh J
|
|
|
|
|
I would like to disable a row (with checkbox) in list control. This makes the user cannot check the checkbox. Any hints on this? Thanks all!
|
|
|
|
|
You can draw the row in grey text to simulate disabling it. See my tutorial on custom draw if you need directions on using custom draw.
As for disabling the checkbox, I think you can do it by handling LVN_ITEMCHANGING, and if the item's state icon (which is how the checkboxes are implemented internally) is about to change, you disallow the change.
You may also need to handle LVN_KEYDOWN and watch for the space bar, because that will also change the state of a checkbox.
|
|
|
|
|
Hello,
I would like to limit access to the MS Access database that my app uses. Ideally, it would not be accessible at all from outside the app. My app will provide means to initialize and copy the database with the copy being accessible. Is there a way to do this either on the MS Access side or the VC++ side?
Thanks.
Paul Ebert
|
|
|
|
|
Hi,
The good news: There is a comprehensive security setup document suite inside the help files of Access. It is relatively easy to read.
The bad news (for me): I could not get it to work reliably and usually couldn't get the options that I wanted. I gave up eventually.
My advice: download the miniSQL server version from vstudio in MSDN. It's called MSDE.
Here's a link to a Jet vs MSDE debate: http://msdn.microsoft.com/library/default.asp?URL=/library/backgrnd/html/msdeforvs.htm&RLD=462.
Here's a link to the MSDE itself: http://msdn.microsoft.com/library/default.asp?URL=/library/backgrnd/html/msdeforvs.htm
Hope this helps.
Kind regards,
Al.
VBer who wants to go back to, but will have to learn again, C++. I'll carry on using VB for the front-end; so when I get proficient at C++/STL can I jump straight to ATL and avoid the MFC?
|
|
|
|
|
When is it appropriate to use the "special" data types defined in the Windows header files such as BOOL, TRUE, and FALSE, & when is it appropriate to use the standard C++ types like bool, true and false? I am programming in MFC, but I see both in code. Anyone who can help end some of this confusion would be appreciated. I understand types like CString, and COLORREF add functionality, but does it matter which one you use with the others I mentioned?
|
|
|
|
|
The SDK is all C APIs, and thus must use BOOL (which is a typedef for int, I believe). They can't use bool because that is a C++ type.
MFC was developed before bool existed in C++, so it uses BOOL. New MFC features use BOOL as well, to maintain consistency.
As for when to use the built-in C++ bool, I myself don't use it much. I'm just used to using BOOL (I started doing Win programming before bool existed). I will use bool's as member variables in classes, or locals in functions. But anytime you pass a flag to an API, use BOOL, because there is no implicit conversion from bool to BOOL (ie, you can't pass a bool for a parameter declared as BOOL). If you do use bool's, you'll have to pepper your code with "bSomeFlag ? TRUE : FALSE" expressions (to explicitly convert from bool to BOOL) which is fugly.
|
|
|
|
|
I do always pass directly a bool to functions expecting a BOOL , never had any problems.
Just the other direction, you must do something like this:
<br />
BOOL b_old = TRUE;<br />
bool b_new = b_old!=0;<br />
|
|
|
|
|
*headscratch* I could've sworn VC complained if you used a bool where a BOOL (or other integral type) was expected. Ah well, my bad.
|
|
|
|
|
Using VC 5, the following code:
BOOL WinBool=TRUE;
bool cppBool=true;
WinBool = cppBool;
cppBool = WinBool;
produces the following:
warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
I think that there are many of us C++ programers that would consider mixing types like that sloppy and we are suspicious of programmers that program like that when it is not necessary.
|
|
|
|
|
My approach is to use bool everywhere remotely possible and to stay as far away from MFC as much as possible . You never know when you might have to port your code or when MS might change their minds on BOOL.
I just use conditional returns like this if a BOOL is required:
if ( true == bState )
{
return TRUE;
}
else
{
return FALSE;
}
when I have to return a BOOL in an overridden function.
I try to never mix BOOL and bool. Even though they serve the same purpose, they are different types and should be treated as such.
|
|
|
|
|
I'm having trouble using Chris's grid in a MFC extension dll. The dll is loaded into an app that isn't mine, and is supposed display a dialog when a method is invoked.
The symptoms are that if I use a custom control resource on my dialog (class=MFCGridCtrl) the dialog fails creation inside Create(). Dunno why, I just don't get a HWND. GetLastError() returns NULL. I can dynamically create the grid after the dialog is created, but then the grid never paints itself. Yes, it is WS_VISIBLE, WS_CHILD, has size, etc. Spy++ "sees" it on the dialog, but I never see it. If I float over a spot where a cell would exist, I can see a tooltip flicker in the upper left corner of the screen. The same code works in my test app, which is not using the extension dll.
I don't have any trouble with the "regular" controls on the dialog, like a CListCtrl.
My setup is pretty funky and I admit up front that the problem may not be the extension dll... One problem is that I am having to link to a non-debug MFC42.dll because the calling app is linked this way. (Although my dll does include debug info.)
Any ideas please?
|
|
|
|
|
I think this problem has been already pointed out in this forum. If I remember well it was a call to AfxGetInsanceHandle() instead of AfxGetResourceHandle() somewhere in the code.
I think it has been fixed in recent updates of the control. Try with a newer version.
|
|
|
|
|