How to add WINAPI code to MFC? - winapi

I had to combine MFC and WinAPI: add WINAPI code to MFC,
the following are MFC and WinAPI code:
MFC code
void MyMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
......
}
WinAPI code
LRESULT CALLBACK Win32Fun(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
......
}
Can I do like this:
void MyMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
Win32Fun(hwnd, msg, wParam, lParam);
}

Yes. There's no magic involved. The fact that the base class of your class is taken from the MFC library doesn't change the fact that it's C++. The WINAPI is C code, and C++ can call C.

Related

Set WH_GETMESSAGE hook makes the system dead

I use SetWindowsHookEx to install a global GETMESSAGE hook in a dll like this:
SetWindowsHookEx(WH_GETMESSAGE,HookProc,hModule,0);
and the the hook procedure within the dll too.But when i called InstallHook(this function is exported from the DLL) to install the GETMESSAGE hook,booom, the system can not respon the mouse operation,the windows on the desktop can be close or move) ,here is my HookProc Code:
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
WCHAR szMsg[MAX_PATH] = { 0 };
PMSG pMsg = (PMSG)lParam;
wsprintf(szMsg, L"MSG_FROM:%08x,MSG_TYPE:%d", pMsg->hwnd,pMsg->message);
OutputDebugString(szMsg);
return CallNextHookEx(NULL,nCode, wParam, lParam);
}
I've read the MSDN for many times,it just said i must process the message if the ncode is HC_ACTION,but,i don't know how to process the message.I think there must be someone else has this problem too, so, hope somebody give some help, and tell me how you process this trouble.
Thanks a lot.

Atl CDialogImpl not showing on DoModal if called from static library

I wrote a super simple ATL dialog inside a project. Even when I noted that every example on the web implemented the CDialogImpl class inline (that is, the class definition and it's implmentation where in the definition itself) I wrote it normally, separating my definition in a .h file and implementation in a .cpp file. This class is summarized below:
CMainDialog.hpp
class CMainDialog: public CDialogImpl<CMainDialog>
{
public:
enum { IDD = IDD_MYDIALOGS_DIALOG};
BEGIN_MSG_MAP(CMainDialog)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
END_MSG_MAP()
CMainDialog();
~CMainDialog();
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled);
LRESULT OnCancel(UINT uMsg, WORD wID, HWND hWndCtl, BOOL& bHandled);
}
CMainDialog.cpp
CMainDialog::CMainDialog()
{
}
CMainDialog::~CMainDialog()
{
}
LRESULT CMainDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
}
LRESULT CMainDialog::OnCancel(UINT uMsg, WORD wID, HWND hWndCtl,
BOOL& bHandled)
{
}
If I call this class from the same project, everything goes fine. The dialog shows. Example:
Calling DoModal
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
CMainDialog dialog;
dialog.DoModal();
return 0;
}
So I converted this project from .exe to static library and removed _tWinMain.
So, if I create a new ATL project, reference my newly created library and call CMainDialog.DoModal ... well, nothing happens. The constructor does get called, but the messages never start dispatching and the program ends inmediatly. Maybe I'm missing something?
I'm totally new to Win32 programming (although definitely not new to c++) so any help would be appreciated.
A static library does not have resources associated with it. Most likely the dialog code is trying to load the dialog template from the program resources but can't find it.

How to use DialogBox in Windows API

I'm learning windows api for some weeks, now I got a problem, my code is like this
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
switch(message){
case(...)
DialogBox(hInstance,MAKEINTRESOURCE(IDD_MYDIALOG),hwnd,(DLGPROC)MyDialogProc);
return 0;
}
bool MyDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
switch (message){
...
}
return false;
}
I don't know what else should I do before I use DialogBox where should I place EndDialog(). IDD_MYDIALOG is a resource file created by myself. I don't understand what is hInstance and how to get it, I think I just need a simple example, than I can know how use DialogBox. Thank you for helping!

Zombie Process after using a Windows subclass callback

I'm using the SetWindowSubclass(...) method of the Windows API to kind of "hook" messages transmitted to a WinProc that is out of the scope of my application.
My application is made of a core and plugins in DLL.
I've implemented such a Subclass in one of my plugins DLL.
I set the Subclass like this:
class MyPlugin
{
private:
static HWND s_OgrehWnd;
UINT_PTR m_uIdSubclass; //The ID of the Subclass WinProc
DWORD_PTR m_pdwRefData;
//....
public:
void MyPlugin::init();
LRESULT CALLBACK MyPlugin::windowProcSubclass(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
void MyPlugin::shutdown();
//....
};
//Set the subclass
void MyPlugin::init()
{
//...
bool resultsc = SetWindowSubclass(
s_hWnd,
MultitouchPlugin::windowProcSubclass,
m_uIdSubclass,
m_pdwRefData
);
//...
}
//The subclass
LRESULT CALLBACK MyPlugin::windowProcSubclass(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch(message)
{
case WM_GESTURE:
return MultitouchPlugin::g_cGestureEngine.WndProc(hWnd,wParam,lParam);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//Remove the subclass
void MyPlugin::shutdown()
{
//shutdown called - unregister stuff here
bool isSublcassed = GetWindowSubclass(s_hWnd, MultitouchPlugin::windowProcSubclass, m_uIdSubclass, &m_pdwRefData);
if(isSublcassed)
{
RemoveWindowSubclass(s_OgrehWnd, MultitouchPlugin::windowProcSubclass, m_uIdSubclass);
}
}
My problem is that when I quit the application, I can see the process that keeps running on in the 'Windows Task Manager' tool.
In debug mode, i've checked that it goes calls RemoveWindowSubclass(), and it does it.
If I remove my plugin with this code, there is no zombie process....
Does somebody has an idea about a solution to this problem?
Thanx in advance for the help

Why SetWindowsHookEx not works in the CLI(which codes in main() instead dllmain,etc.)?

#include <stdio.h>
#include <windows.h>
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
printf("Keyboard event, nCode = %d, wParam = %d, lParam = 0x%.8X\n", nCode, wParam, lParam);
return (LRESULT)NULL;
}
void main() {
HHOOK HookHandle = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, (HINSTANCE) NULL, GetCurrentThreadId());
printf("Hook handle = 0x%.8X\n", HookHandle);
MSG message;
while (GetMessage(&message,NULL,0,0)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
UnhookWindowsHookEx(HookHandle);
}
Expected it outputs something like "keyboard event...", but it does not work, it always keep silent whatever I type.
The compile options is simple: gcc -o test.exe test.c
Most (if not all) of these hooks have to be injected into the target application(s), so they must be implemented in a DLL.
From the documentation of the KeyboardProc callback function:
The system calls this function
whenever an application calls the
GetMessage or PeekMessage function and
there is a keyboard message (WM_KEYUP
or WM_KEYDOWN) to be processed.
Console applications don't use the message queue to handle input, so your hook will never be called.
You could try using a low-level keyboard hook (WH_KEYBOARD_LL). Even though that's a global hook, you don't need to use a DLL: as mentioned in the Remarks section of the documentation, the hook code is not injected in other processes. The problem with this approach of course is that you'll get notifications for all key events in the system (not just the ones in your program).

Resources