|
Nope!
Child controls are also windows. So when you click a CButton control, the control will handle the message rather then passing it on to the parent window.
A student knows little about a lot.
A professor knows a lot about little.
I know everything about nothing.
|
|
|
|
|
thanks for the answer.
But this is what i understand about the message handling mechanism of MFC.
When a control say a button is clicked it invokes its own wndproc which does what ever is required( say showing it in depressed state). Thiis because every control is actually a window.And then it sends anotification to the parent WM_COMMAND( in this case with msg as BN_CLICKED). Right? If this was the case then i Should be able to handle BN_CLICKED in parent.
Please correct me if i am wrong.
|
|
|
|
|
I think I got it, BN_CLICKED is a notification, not a command, and will be received into a WM_NOTIFY message.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
You can process the message in the parent window. The only thing you have to do is map a message handler to the desired action in your windows message map:
<br />
BEGIN_MESSAGE_MAPE(YourWindow, DerivedFrom)<br />
ON_BN_CLICKED(IDD_YOUR_BUTTON_ID, memberfxn)<br />
END_MESSAGE_MAP()<br />
Hope this helps
A student knows little about a lot.
A professor knows a lot about little.
I know everything about nothing.
|
|
|
|
|
"You can process the message in the parent window. The only thing you have to do is map a message handler to the desired action in your windows message map:
BEGIN_MESSAGE_MAPE(YourWindow, DerivedFrom)
ON_BN_CLICKED(IDD_YOUR_BUTTON_ID, memberfxn)
END_MESSAGE_MAP() "
That is correct but my requirement is slightly different. I dont want to provide a static macro like the one above. Because my application reads what controls are to be rendered from datastructure. It reads from the datastructure that it need to create a button with xyz style , a textbox with some wdth and style etc.
Now i cannot use static statemenst as above. So what i wanted to do was intercept the default message handling mechanism. I wanted to override the pretranslate message for this and then from the MSG structure get what was the event fired and who fired it process it in pretranslatemessage and return.
|
|
|
|
|
Hello,
One way to go is subclassing the button control. This[^] article will tell you more about subclassing.
The other way to go is creating your own button control by deriving your custom button class from CButton.
From there you can make the button do what you want it to do. For exemple, you can send a user defined window message to your window that'll handle the button's actions.
A student knows little about a lot.
A professor knows a lot about little.
I know everything about nothing.
|
|
|
|
|
I dont wanna go subclass way because i dont wanna subclass "n" classes. Since my ui may have n differnt controls.
|
|
|
|
|
i tried notify but no change. I cannot handle it still.
|
|
|
|
|
I's say so, a BN_CLICKED notification, to be precise. What's your observed behavior?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
it could be a bn_clicked, en_change, cbn_selchanged any message( command or notification ).
I donot agree that BN_CLIcKED is a wm_notify type because CButton is a standard control and not a common control.
|
|
|
|
|
Maybe you're right, but I'd try anyway, it's a few of lines of code and will make you 100% sure.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Control notifications are handled via WM_COMMAND not WM_NOTIFY. If you wish to override the original message that caused the event like a keystroke, mouse move, etc, then you subclass the control and override the appropriate window message. If you want to override the notification (which sounds like what you want), then in the parent class (dialog) you have three options:
1. Handle the notification message. Add ON_BN_CLICKED function for example.
2. Override the OnCommand message.
Inside OnCommand you can do something like:
BOOL CYourDialog::OnCommand( WPARAM wParam, LPARAM lParam )
{
if( LOWORD(wParam) == IDC_CTRL_ID && HIWORD(wParam) == BN_CLICKED )
return( CDialog::OnCommand(wParam, lParam) );
}
3. Override PreTranslateMessage and process there.
BOOL CYourDialog::PreTranslateMessage( MSG *pMsg )
{
if( pMsg->message == WM_COMMAND )
{
if( LOWORD(pMsg->wParam) == IDC_CTRL_ID && HIWORD(pMsg->wParam) == BN_CLICKED )
}
return( CDialog::PreTranslateMessage(pMsg) );
}
I'm not sure what you're trying to do, but usually it's better to your command processing using either method 1 or 2. Rarely do I have a need to override PreTranslateMessage.
|
|
|
|
|
Correct, but assume that the controls on the dialog are dynamically created such that at time of coding i dont know as to what are the controls on the dialog. So i cannot provide the macro ON_BN_CLIKCED(btnid, handler).
The reason i want to over ride the pretranslatemessage is to catch what ever goes thru the message loop filter the messages i am intersted in by using and ifelse construct like you mentioned. But the main question is my handler in pretranslate never gets invoked Why???
Cmydialog::PreTranslateMessage(MSG *msg)
{
if( pMsg->message == WM_COMMAND )
{
if(LOWORD(pMsg->wParam)==IDC_CTRL_ID && HIWORD(pMsg->wParam)==BN_CLICKED)
{
UINT controlID = LOWORD(pMsg->wParam);
if (controlID == someidofinterest)
{
//do what i want it to do
}
}
}
}
|
|
|
|
|
Overriding OnCommand is the correct place to do this.
Why isn't PreTranslateMessage being called?
I had to think about this for a bit and reach back into the message loop days. PreTranslateMessage is not called for every type of message sent to a window. It is primarily a pre-cursor beforing calling the API function TranslateMessage.
TranslatesMessage's primary function is to convert key strokes into WM_CHAR messages or into command accelerators.
MFC's message loop, in a nutshell, looks like this:
while( GetMessage(pMsg) )
{
if( ! AfxPreTranslateMessage(pMsg) )
{
::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
}
}
The key thing to note here as the GetMessage does not return for every message received by the application. It only returns for WM_QUIT, posted messages (I think), and keyboard handling. WM_COMMAND messages are sent directly to the window procedure from within GetMessage. The reason for this is that there is no translation necessary.
Think of it this way. The purpose of PreTranslateMessage/TranslateMessage is not to perform some action when a message is received. That's what the appropriate message handlers are for (like OnCommand). It's job is to convert message IDs from one to another as needed. For example if you press "Ctrl+N" it converts the WM_KEYUP to WM_COMMAND (ID_FILE_NEW).
|
|
|
|
|
thanks a lot.
Your explanation solved it all. Is this behaviour of getMessage and pretranslate/translate message documented somewhere in msdn so that i could dig more into it.
|
|
|
|
|
It probably is somewhere, but I couldn't say where. I discovered that partly through trial and error and partly gleaned from the many varying documents in MSDN. If you look at the docs for the GetMessage function there's a sentence that says:
"During this call, the system delivers pending messages that were sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function".
The key phrase being During this call. That's the only one I can think of off the top of my head.
|
|
|
|
|
Anyone has an ideea about opening a file from command-line in a dialog-based application ?
A link to a article or something whould be great. thanks.
|
|
|
|
|
If you want to run some DOS commands (also including opening a file) ShellExecute[^] is the way to go!
A student knows little about a lot.
A professor knows a lot about little.
I know everything about nothing.
|
|
|
|
|
Regardless of the type of application (dialog, SDI, or MDI), you simply need to look at the m_lpCmdLine member variable of CWinApp .
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
DavidCrow, if you could extend the explications a liitle bit more, i would be gratefull. (something about WinMain call ?)
|
|
|
|
|
I'm not sure what you mean by "extend the explications," but maybe this will help.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
Hi all,
I’m writing my first DLL. Any help would be greatly appreciated. When I run the DLL function fnCopyFile I get an error: "Unhandled exception at 0x77f5a58 in MyTest.exe." The DLL function works but this error occurs when popping out of the DLL’s fnCopyFile function.
Here is my DLL code:
Main program:
#include <string>
using namespace std;
typedef void (WINAPI *FncArcNewFile)(string str1, short si, string str2, short st);
int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE hinstLib;
FncArcNewFile FncCopy;
short iii = 4;
hinstLib = LoadLibrary(TEXT("C:\\ProgramFiles\\CasArc.dll"));
FncCopy = (FncArcNewFile)GetProcAddress((HMODULE)hinstLib, "fnCopyFile"); //Name of the function in the DLL.
FncCopy(string("c:"), iii, string("C:\\Custodian Working Dir \\0001_0001_0001_0002.txt"), iii);
FreeLibrary(hinstLib);
}
CasArc.dll program:
.H file
#include <string>
#include "CasArc.h"
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) void fnCopyFile(string pstrDir, short EVarIn_y, string pstrFile, short EVarIn_l);
.CPP file:
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) void fnCopyFile(string pstrDir, short EVarIn_y, string pstrFile, short EVarIn_l)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
DWORD dwAttrs;
//*ret_indicator = 0;
hFind = FindFirstFile(pstrFile.c_str(), &FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
pstrDir += "\\";
pstrDir += FindFileData.cFileName;
if (CopyFile(pstrFile.c_str(), pstrDir.c_str(), FALSE))
{
dwAttrs = GetFileAttributes(FindFileData.cFileName);
//if ( GetLastError() != 0 )
// ErrorMessage();
if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))
{
SetFileAttributes(pstrDir.c_str(), dwAttrs | FILE_ATTRIBUTE_READONLY);
}
}
else
{
ErrorMessage();
}
}
else
{
ErrorMessage();
}
FindClose(hFind);
}
|
|
|
|
|
Hi,
I would like to know that how can i detect memory leaks in an application with information such as which file had memory leak and line number.
I have a dll which i dynamically load. That dll is using a big static library OpenSSL and i have included the DLL in the exe based project.
Now what i find through standard outputwindow after closing of application is that there are huge memory leaks like,
{18643} normal block at 0x012F8AE0, 12 bytes long.
Data: < / C IT> 20 8B 2F 01 00 00 00 00 43 E6 49 54
I want to know the exact file and line number which comes through DEBUG_NEW i think, but the library code is ansi c code and it 500 or more file so any ideas how can i debug to the exact location.
Any good memory profiler available.
Thank You.
|
|
|
|
|
Is there in this library a common header file that is always included?
Papa
while (TRUE)
Papa.WillLove ( Bebe ) ;
|
|
|
|
|