|
|
i have a program like this:
main app is CMyApp ::CWinApp
i give an ID for a button on the main window:
ID_MY_BUTTON
i want to handle the click message in CWinApp's member function
so i mapped the message as:
ON_COMMAND(ID_MY_BUTTON, OnMyButton);
and write the code for the function
actually it works very well
but the question comes up when i tried this:
::postmessage(hMainWnd, ID_MY_BUTTON,Null,Null)
i used hMainWnd because i believe the message mapping net can automatically send the message to the main thread.
but, finally, i found this does not cause the OnMyButton to be called.
i also tried this one:
::PostMessage(hMainWnd, WM_COMMAND, ID_MY_BUTTON, 0)
but it still doesn't work
so, how should i send this ID_MY_BUTTON message so that the main thread can handle it?
thanks alot!
-- modified at 18:11 Monday 31st July, 2006
|
|
|
|
|
I think generally its a bad idea to mix the mfc message handling stuff with the win32 functions. It should all work ok but your program will be easier to maintain if you pick one and stick with it.
You need to send the message to the parent window of the button. Off the top of my head you should try something like
MyButton->GetParent()->SendMessage(...);
Objects in mirror are closer than they appear
|
|
|
|
|
|
Hi,
Having some trouble getting a char* from the Stupinfo.hStdOutput which is a HANDLE.
STARTUPINFO Stupinfo; PROCESS_INFORMATION ProcessInfo;
char* procnm="Test.exe";
HANDLE h;
LPWSTR lpwString = L"";
lpwString = (LPWSTR)procnm;
IntPtr StdOutput;
Stupinfo.dwX=0;
Stupinfo.dwY=0;
Stupinfo.hStdOutput=h;
CreateProcess(NULL, lpwString, NULL, NULL, FALSE, 0, NULL, NULL, &Stupinfo, &ProcessInfo);
char* tesst="test";
tesst=Stupinfo.hStdOutput;
send(AcceptSocket, tesst, strlen(tesst), 0);
I know its not going to be easy unless there is simple convesion. but ive seen methods which output to .txt file for some reason.. but i dont see why you couldn't get the char*
Please Help
-- modified at 17:31 Monday 31st July, 2006
|
|
|
|
|
You have to create a HANDLE *before* calling CreateProcess. Usually people use CreatePipe, but you can also pass socket handles as well. Then you ReadFile/WriteFile to the handle to read/write data.
|
|
|
|
|
Could you please show me some code?
STARTUPINFO Stupinfo; PROCESS_INFORMATION ProcessInfo;
char* procnm="Test.exe"; char* tesst; BOOL readIntoMemory;
HANDLE h, hWritePipe; LPSECURITY_ATTRIBUTES lpPipeAttributes; DWORD nSize;
LPWSTR lpwString = L"";
lpwString = (LPWSTR)procnm; LPVOID inBuffer; DWORD nBytesToRead; LPDWORD nBytesRead, lpNumberOfBytesWritten;
DWORD bytestowrite;
IntPtr StdOutput;
Stupinfo.dwX=0;
Stupinfo.dwY=0;
Stupinfo.hStdOutput=h;
CreateProcess(NULL, lpwString, NULL, NULL, FALSE, 0, NULL, NULL, &Stupinfo, &ProcessInfo);
ReadFile( h, inBuffer, nBytesToRead, nBytesRead, NULL);
WriteFile( (HANDLE)AcceptSocket, inBuffer, bytestowrite, lpNumberOfBytesWritten, NULL);
how to use the WriteFile to get a char*?? and do i have it setup correctly?
-- modified at 19:25 Monday 31st July, 2006
|
|
|
|
|
Hi!
We have a class CDriver which inherits from IDriver. CDriver is defined in a library, CDriver.lib. CDriver.lib is added to the library definition of the project settings, and we have CDriver.h included in the file list for the project.
If we create a new class, CMyDriver, which inherits from CDriver, and add member variables to it, when we run the app, things crash when the destructor is called. If we remove the member variables things work properly. We can add as many member functions as we want, but cannot add member variables.
We dont understand that's happening. Any ideas? This is basic inheritance!! This is weird that I cannot add member variables.
Help!?!?!?
-C
|
|
|
|
|
sounds less like an inability to add member variables, and more a case where something is happening in the destructor of the CMyDriver class that crashes the app.
can you step into the destructor in the debugger ?
Why donchoo take a peekchur mayn?
OK, cleeeeek
|
|
|
|
|
I cannot step through it in the debugger as it simply crashes.
|
|
|
|
|
When you say, "CDriver is defined in a library", I assume you mean a DLL. If that is the case, then search for any old copies of the DLL that may be getting loaded. For example, did you previously copy it to the Windows directory? If you find old copies, rename them and make sure the current DLL is in the app's exe directory, and try again.
This may not be the cause of the crash, but it is a good starting point.
Best wishes,
Hans
|
|
|
|
|
CDriver is defined in a library (.lib) file that statically linked at compilation. I'm pretty sure its loading the correct lib file, but I'll double check.
|
|
|
|
|
Is the destructor in CDriver declared as virtual?
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
No, the destructor is not virtual. Should this be? If so, I guess I've forgotten basic C++ inheritance rules in which my question makes me look silly!!
|
|
|
|
|
Yes. The destructor MUST be declared virtual if you plan to derive from it. Here is why:
class Base
{
public:
Base() {}
~Base() {}
private:
};
class Derived : public Base
{
public:
Derived() {}
~Derived() {}
private:
int m_MyInt;
};
void main()
{
Base* pB = new Derived;
delete pB;
}
What happens is that the ~Base() destructor is called, but not the ~Derived(). Thus, m_MyInt stays allocated in memory (that is, the portion of memory allocated for a Base object is freed, but not that for Derived). This is called memory slicing (see "Effective C++" by Scott Meyers for more details).
The rule of thumb: If your class is meant to have classes derived from it, it MUST have a virtual destructor.
This problem can (and will) blow up your memory eventually (either stack or heap or both).
-- modified at 16:48 Monday 31st July, 2006
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Thanks. This was a good catch. Unfortunately, I still get an 'access violation' at destructor. I set a breakpoint in my derived class CMyDriver, and it doesnt step into the CDriver nor IDriver.
I'm just confused. If I remove the member variables from the class definition, things work fine.
|
|
|
|
|
Any way you can actually show the code (slimmed down) you are using? The definitions of all 3 classes and the implementations for the destructors would be helpful in evaluating your problem.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
CIDriver, CDriver and CMyDriver all have virtual destructors.
__declspec(dllexport) CIDriver* InitDriver(CIKernel* i_hKernel)
{
//__asm { int 0x03 }
CMyDriver* hUserDriver = new CUserDriver;
hUserDriver->Create(i_hKernel);
return (CIDriver *)hUserDriver;
}
__declspec(dllexport) void EndDriver(CIDriver* i_hIDriver)
{
CMyDriver * hUserDriver = (CMyDriver *)i_hIDriver;
hUserDriver->Destroy();
delete hUserDriver;
}
My app crashes at the 'delete hUserDriver'. EndDriver is an exposed interface call that another DLL calls to detroy the driver. hUserDriver->Destroy() destroy all internal structures of CDriver (not CMyDriver, as this function isnt overloaded in CMyDriver). CMyDriver is not referencing any objects destroyed by the Destroy call. Nothing is available in the debugger as its all assembly at that point.
In the class definition for CMyDriver, if I add public member variables, it crashes on the delete. If I make them global (file scope), it doesnt crash.
I"m wondering if its looking at the class size or something. I'm just confused.
-C
|
|
|
|
|
Wheatbread wrote: CMyDriver * hUserDriver = (CMyDriver *)i_hIDriver;
hUserDriver->Destroy();
delete hUserDriver;
}
My app crashes at the 'delete hUserDriver'. EndDriver is an exposed interface call that another DLL calls to detroy the driver. hUserDriver->Destroy() destroy all internal structures of CDriver (not CMyDriver, as this function isnt overloaded in CMyDriver). CMyDriver is not referencing any objects destroyed by the Destroy call. Nothing is available in the debugger as its all assembly at that point.
Does Destroy get called from any of those destructors (or is anything that is cleaned up in Destroy also cleaned up in any of the destructors)?
Wheatbread wrote: CMyDriver * hUserDriver = (CMyDriver *)i_hIDriver;
Just FYI, this is a dangerous cast. You should use dynamic_cast or reinterpret_cast to do this (and check the return value). This shouldn't be the cause of your problem, though.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Hi,
I am having a trouble with my CListCtrl
I need to get the subitem number.
void CDlg::OnItemchangedList(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
int nItem = pNMListView->iItem;
int nSubItem = pNMListView->iSubItem;
*pResult = 0;
}
The above is returning the nItem number properly. But it is always giving zero for nSubItem.
Why is this happening?
Thanks.
Tara
Fortitudine Vincimus!
|
|
|
|
|
How many subitems does it have? Can you post the code that you use to add the subitems?
Best wishes,
Hans
|
|
|
|
|
I use SetItemText to add items to the list.
The items are read from mdb database. The number varies from two to about 50.
Fortitudine Vincimus!
|
|
|
|
|
Just respond to the NM_CLICK notification message.
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
I am using CEditList class got from codeproject. I have added a lot of other features to it. There is already an NM_CLICK message handled there. If I try to add one more message in the dialog box class, it does not work. But as such, when I put a message box in the onClick function in CEditList, it correctly gave the column number.
Fortitudine Vincimus!
|
|
|
|
|
|