|
seems i found it!
change
CBitmap* pOldBitmap
to
HBITMAP pOldBitmap
t!
|
|
|
|
|
Hello,
I wonder if there is a function like SendKeys function in VC++.
İf not, how can i send keystrokes to other applications? Do i have to use SendMessage or PostMessage functions?
Mustafa Demirhan
|
|
|
|
|
Yes you should use
SendMessage or PostMessage
Something like
SendMessage(h_yourWnd,WM_KEYDOWN,...)
you should chek help for WM_KEYDOWN message to get info about parameters
regards,
/REMUS
|
|
|
|
|
Yes, but be sure to send WM_KEYUP messages for each character just after each WM_KEYDOWN, maybe with some delay.
|
|
|
|
|
Look up the keybd_event() and SendInput() APIs.
|
|
|
|
|
Hello,
I have a big problem about modeless dialogs. When i create the dialog like
CString msg("Message");
CShowMessage *swRem=new CShowMessage(msg);
swRem->Create(IDD_SHOWMESSAGE_DIALOG);
swRem->ShowWindow(SW_SHOW);
it works fine.(This dialog gets a string as a parameter).
However, if i call it like this
CString msg("Message");
CShowMessage swRem(msg);
swRem.Create(IDD_SHOWMESSAGE_DIALOG);
swRem.ShowWindow(SW_SHOW);
it appears first but then immediately dissappers.
This is a big problem since i have to delete the new dialog if i use the first code. To delete this dialog, i pass the pointer of the dialog to itself as a parameter and the dialog deletes itself. However, this is not a good programming practice.
I need your suggestions.
Mustafa Demirhan
|
|
|
|
|
Usually disapears because the scope of variable
swRem is finished.
The best way is the first solution and on WM_CLOSE message (should be more) try a "delete this"
It should work.
regards,
/REMUS
|
|
|
|
|
Actually, the delete this; call should go in an override of PostNcDestroy() .
|
|
|
|
|
I suspect that your code :
CString msg("Message");
CShowMessage swRem(msg);
swRem.Create(IDD_SHOWMESSAGE_DIALOG);
swRem.ShowWindow(SW_SHOW);
is in some function. Once the function returns,
static local variables are automattically destroyed.
(in your case , msg and swRem).
One thing to try is to make these variable global by
putting the lines :
CString msg("Message");
CShowMessage swRem(msg);
at the top of your CPP file.
|
|
|
|
|
I assume that the CShowMessage constructor stores the parameter (msg) as a member variable for itself, so making it global is not necessary and would probably not accomplish anything even if it were global; the constructor does not use the variable, it uses the parameter.
Also, C++ classes usually make it unnecessary to use global variables, so:
CShowMessage swRem(msg);
could be a member variable in the class where it is being used.
|
|
|
|
|
The documentation for modeless dialogs has been inadequate so I wrote some notes that might help people. See:
http://home.socal.rr.com/samhobbs/VC/ModelessDialogs.html
In that page I reference a MS KB article that was written after I wrote my notes.
|
|
|
|
|
Hello,
I wonder if i can catch all mouse and keyboard events of all windows from a hidden application in VC++/MFC. For example, i want to do special things if some key pairs are pressed (like in macro magic).
Mustafa Demirhan
|
|
|
|
|
Usualy you must obtain messages from windows and you could do this by "subclassing" every process. For more informations read in MSDN.(try a serch using "Subclassing Windows" and you will find some TehnicalArticles usefull enough about this)
regards,
/REMUS
|
|
|
|
|
I have certainly heard of subclassing windows but not subclassing processes. I doubt that such a thing is possible.
|
|
|
|
|
You will need to use SetWindowHook. Hooking can be rather complex, so be sure to read the documentation on it carefully.
|
|
|
|
|
Most all documentation relevant to SetWindowsHookEx is listed in:
http://home.socal.rr.com/samhobbs/VC/Hooks.html
It is definitely advanced stuff and I think that anyone attempting to implement such stuff need to expect to spend at least two weeks, probably a month learning what needs to be learned to be able to use the capability and related things effectively, safely and efficiently.
|
|
|
|
|
I have 2 views in a splitter window, and I don't want to allow the user to move from one view to the other (by clicking) when the current view is still in edit mode.
I have try to use OnActivateView and OnKillFocus but iseems already too late.
I would appreciate any suggestion.
Thank you
|
|
|
|
|
From the MSDN
"Catching hardware exceptions is still possible with the synchronous model. However, some of the unwindable objects in the function where the exception occurs may not get unwound, if the compiler judges their lifetime tracking mechanics to be unnecessary for the synchronous model."
The above statment make me feel uneasy about sync model, although it seems much better since it generates less code? Can anyone makes sense on what the above is trying to say plz?
|
|
|
|
|
Do you know how to adjust the size of property sheet/page? I have 4 pages in the property sheet. However, when i show the property sheet, it is larger than what i expect (it has some spaces on the right). How can i make the pages best fit into the sheet?
Thanks all!
|
|
|
|
|
|
I am looking for UI solution in which a dockable window which can contain multiple toolbars inside it. It seems that toolbar has to be a child window to either the Frame Window or a popup window or a CDialog derived window. However, none of these windows are dockable.
The problem with the main frame window is that as number of toolbars increase the size of the docked area increases. This causes loss of space which is needed
for the main child graphics window. And I can't afford to
resize the main graphics window when a toolbar is docked or
undocked because it is too expensive to do that. This is
because the main MDI Child window holds huge amount of graphic intensive data which makes it very slow to be resized frequently.
I will really appreciate any suggestions that anyone may have.
thanks
shailesh
|
|
|
|
|
I have an app and I need to pass a string to it from another app. While I can send a registered message back and forth, I can't send a pointer. I'm using ::SendMessage() and the string pointer as the WPARAM like this:
::SendMessage(HWND_BROADCAST, MY_REGISTERED_MESSAGE, (WPARAM)((LPCSTR)m_sMyCString), 0);
The target app gets the message, but the pointer is NULL (or invalid).
Is there a way to do this with messages like this, or am I gonna have to kludge something up with shared memory?
|
|
|
|
|
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
|
|
|
|