Programmatically delete item from Windows Recycle Bin without UI dialog - c++

I'm using IContextMenu with "delete" verb to erase items from recycle bin, but it brings up the UI dialog even if I useCMIC_MASK_FLAG_NO_UI flag. Is there another way to delete files from recycle bin without showing the dialog?
IContextMenu* contextMenu;
recycleBin->GetUIObjectOf(0, 1, (LPCITEMIDLIST*)(&pidl), IID_IContextMenu, 0, (LPVOID *)&contextMenu);
CMINVOKECOMMANDINFO ci;
memset(&ci, 0, sizeof(ci));
ci.fMask = CMIC_MASK_FLAG_NO_UI;
ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
ci.lpVerb = "delete";
contextMenu->InvokeCommand(&ci);
contextMenu->Release();
The full code including recycle bin object initialization and items enumeration is on gist

You can install a WH_CBT hook, and in its callback watch for an nCode of HCBT_CREATEWND. If you get a matching class name ('#32770 (Dialog)' ?) and a matching title either return a nonzero value from the callback, you can send BM_CLICK to click Yes button and the dialog will be closed automatically.
Code Sample:
main.cpp
#include <iostream>
#include <windows.h>
#include <Ole2.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <string>
#pragma comment(lib,"Shlwapi.lib")
HHOOK g_hhook;
int main()
{
OleInitialize(0);
HINSTANCE hinstDLL = LoadLibrary(TEXT("D:\\xxx\\Dll_WH_CBT\\Debug\\Dll_WH_CBT.dll"));
HHOOK(*AttachHookProc)(DWORD);
AttachHookProc = (HHOOK(*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook");
void(*RemoveHooks)(DWORD);
RemoveHooks = (void(*)(DWORD))GetProcAddress(hinstDLL, "RemoveHooks");
IShellFolder* desktop;
if (FAILED(SHGetDesktopFolder(&desktop))) {
std::cerr << "Failed to get desktop fodler" << std::endl;
return -1;
}
...
IEnumIDList* enumFiles;
if (FAILED(recycleBin->EnumObjects(0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS |
SHCONTF_INCLUDEHIDDEN, &enumFiles)))
{
std::cerr << "Could not enumerate recycle bin objects" << std::endl;
recycleBin->Release();
return -1;
}
AttachHookProc(0);
...
RemoveHooks(0);
enumFiles->Release();
recycleBin->Release();
OleUninitialize();
return 0;
}
Dll:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <Windows.h>
HMODULE thisModule;
HHOOK g_hhook;
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
switch (nCode)
{
case HCBT_CREATEWND:
{
HWND File_Window = FindWindow(L"#32770", L"Delete File");
HWND Folder_Window = FindWindow(L"#32770", L"Delete Folder");
if (File_Window)
{
HWND yes = FindWindowEx(File_Window, NULL, L"Button", L"&Yes");
SendMessage(yes, BM_CLICK, 0, 0);
SendMessage(yes, BM_CLICK, 0, 0);
}
if (Folder_Window)
{
HWND yes = FindWindowEx(Folder_Window, NULL, L"Button", L"&Yes");
SendMessage(yes, BM_CLICK, 0, 0);
SendMessage(yes, BM_CLICK, 0, 0);
}
break;
}
default:
break;
}
return CallNextHookEx(g_hhook, nCode, wParam, lParam);
}
#ifdef __cplusplus //If used by C++ code.
extern "C" { //we need to export the C interface
#endif
_declspec(dllexport) HHOOK AttachHook(DWORD threadID) {
g_hhook = SetWindowsHookEx(WH_CBT, CBTProc, thisModule, threadID);
return g_hhook;
}
#ifdef __cplusplus
}
#endif
extern "C" { //we need to export the C interface
__declspec(dllexport) void RemoveHooks(DWORD)
{
UnhookWindowsHookEx(g_hhook);
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
thisModule = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

Related

How to set global hook WH_CBT in winapi

I would like to create global WH_CBT hook using winapi. I create dll with this hook. When I using this
dll in other application ( this app load dll and start hook - let it name be abc.exe ) I can load that dll, get functions ( with hook and unhook ) and see the output, but only from that abc.exe's thread. I would like to see messages like HCBT_CREATEWND from other windows ( not only from abc.exe window ). I set the fourth arg in SetWindowsHookEx to 0, so I except to set the global hook.
In abc.h:
HINSTANCE hDll;
typedef void( * MYPROC )( void );
MYPROC funHook, funUnhook;
In abc.exe window constructor (abc.cpp):
hDll = LoadLibrary( L"probaHook" );
if( hDll )
{
funHook =( MYPROC ) GetProcAddress( hDll, (LPCSTR) "hook" );
funUnhook = ( MYPROC ) GetProcAddress( hDll, (LPCSTR) "unhook" );
qDebug()<<funHook<<funUnhook;
if( funHook )
{
funHook();
}
}
In abc.exe window destructor (abc.cpp):
if( funUnhook )
{
funUnhook();
}
FreeLibrary( hDll );
In probahook.h ( file with dll declaration functions ):
#ifndef PROBAHOOK_H
#define PROBAHOOK_H
#include "probaHook_global.h"
#include "windows.h"
LRESULT CALLBACK cbtHookProc( int code, WPARAM wParam, LPARAM lParam );
extern "C" PROBAHOOK_EXPORT void hook( void );
extern "C" PROBAHOOK_EXPORT void unhook( void );
class PROBAHOOK_EXPORT ProbaHook
{
public:
ProbaHook();
};
#endif // PROBAHOOK_H
In probaHook_global.h:
#ifndef PROBAHOOK_GLOBAL_H
#define PROBAHOOK_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(PROBAHOOK_LIBRARY)
# define PROBAHOOK_EXPORT Q_DECL_EXPORT
#else
# define PROBAHOOK_EXPORT Q_DECL_IMPORT
#endif
#endif // PROBAHOOK_GLOBAL_H
In probahook.cpp:
#include "probahook.h"
#include <QDebug>
#include <QFile>
HHOOK hhook = NULL;
HINSTANCE hInst = NULL;
LRESULT CALLBACK cbtHookProc( int code, WPARAM wParam, LPARAM lParam )
{
if( code < 0 ) return CallNextHookEx( 0, code, wParam, lParam );
qDebug()<<code;
if( code == HCBT_CREATEWND )
{
QFile file(R"(C:\Users\tom\Desktop\def.txt)");
file.open(QIODevice::WriteOnly | QIODevice::Append);
file.write(QString::number(GetCurrentThreadId()).toStdString().c_str());
file.write("\n");
file.close();
return 0;
}
return CallNextHookEx( 0, code, wParam, lParam );
}
ProbaHook::ProbaHook(){}
BOOLEAN APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
hInst = hModule;
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void hook( void )
{
hhook = SetWindowsHookEx( WH_CBT, cbtHookProc, hInst, 0 );
}
void unhook(void)
{
UnhookWindowsHookEx( hhook );
}
The output from def.txt is:
17192
17192
17192
17192
17192
17192
17192 is my abc.exe thread. Of course when abc.exe is running I try open other windows.
qDebug() in cbtHookProc of course produce output like: 4,6,0, but only from abc.exe window.

About WH_CBT hook

I'm trying to use SetWindowsHookEx to install WH_CBT hook on global to inject the DLL into other process. Now I have the inject.exe, ExampleWindow.exe, inject.dll, let me show you the code.
1.code piece of inject.exe
#include <windows.h>
int main()
{
HHOOK hhook = NULL;
HMODULE dll = LoadLibrary(_T("D:\\projects\\CppDemon\\Release\\HookDemoDll.dll"));
HOOKPROC pfn = (HOOKPROC)GetProcAddress(dll, "MyCBTProc");
if (pfn == NULL)
{
printf("can not get MyCBTProc,press any key to exit\n");
getchar();
return 0;
}
printf("press any key to continue hook\n");
getchar();
hhook = SetWindowsHookEx(WH_CBT, pfn, dll, 0);
if (NULL == hhook)
{
printf("%d\n", GetLastError());
}
printf("press any key to unhook\n");
getchar();
UnhookWindowsHookEx(hhook);
return 0;
}
2.code piece of inject.dll
#ifdef __cplusplus
extern "C"
{
#endif
extern "C" __declspec(dllexport) LRESULT MyCBTProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam);
#ifdef __cplusplus
}
#endif
LRESULT MyCBTProc(_In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
DWORD pid = 0;
TCHAR buffer[128] = { 0 };
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
pid = GetCurrentProcessId();
_stprintf_s(buffer, 128, _T("[+] PID = %d"), pid);
OutputDebugString(buffer);
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
The ExampleWindow.exe is a test case for inject when the named window is created.
When I run inject.exe and everything goes well, the inject.dll has been loaded and the the debug message is output correct, and the PCHUNTER(this is an ARK tool) can detect the WH_CBT message hook in module inject.exe. Then, I run the ExampleWindow.exe, there also can output the debug message.
After this action, I refresh the message hook windows in PCHUNTER ,the WH_CBT hook message has disappeared from the control, and the inject.dll not injected in the ExampleWindow.exe at all.THis is not my expect result.
I don't know how this happens. I hope someone can help me find the cause of this problem.

SetWindowsHookEx, identifying the windows dialog where the mouse is pointing

This is another question I have related to setWindowsHookEx, I have written small Application to hook dll into windows calculator applicatio. Basically, exe application inject the dll into calculator and it monitors all the mouse down events happening at the calculator application. And currently , I am able to disable all the mouse down events happening at the calculator. however, I want to get it done based on the location the mouse is pointing. Specifically, when the mouse button is clicking on specific menu bar item. I tried to get this done by using GetWindowText to retrieve the text where button is pointing, but most of the time it return the window text instead of the window item ( menu item) it is pointing. Following is the code that I have written for this. Any idea on how to disable a particular window element on menu bar.
EXE code which call SetWindowsHookEx
// program.exe.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <string>
#include <io.h>
using namespace std;
void Usage()
{
printf("Usage: InjectDLL pid path-to-dll [-privilege]");
}
int _tmain(int argc, char* argv[])
{
/*
* Load library in which we'll be hooking our functions.
*/
HMODULE dll = LoadLibrary(L"C:\\drivers\\dllinject.dll");
if (dll == NULL) {
printf("The DLL could not be found.\n");
getchar();
return -1;
}
/*
* Get the address of the function inside the DLL.
* _hookmethod#12 is used to hook into 32bit applications
*/
//HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "_hookmethod#12");
HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "hookmethod");
if (addr == NULL) {
printf("The function was not found.\n");
getchar();
return -1;
}
/*
* Hook the function.
*/
DWORD procID=0;
HWND targetWnd = FindWindowA("CalcFrame", "Calculator");
wchar_t msgBuf[1024] = L"";
wchar_t msgBuf2[1024] = L"";
wsprintf(msgBuf, L"the thread Id is : %d , process id is : %d ", threadID, procID);
OutputDebugString(msgBuf);
//
//WH_KEYBOARD_LL
HHOOK handle = SetWindowsHookEx(WH_GETMESSAGE, addr, dll, threadID);
//HHOOK handle = SetWindowsHookEx(WH_CALLWNDPROC, addr, dll, threadID);
//HHOOK handle = SetWindowsHookEx(WH_MSGFILTER, addr, dll, threadID);
DWORD x = GetLastError();
wsprintf(msgBuf2, L"the last error is %d", x);
OutputDebugString(msgBuf2);
if (handle == NULL) {
printf("The KEYBOARD could not be hooked.\n");
}
else{
printf("Program successfully hooked.\nPress enter to unhook the function and stop the program.\n");
}
/*
* Unhook the function.
*/
getchar();
UnhookWindowsHookEx(handle);
return 0;
}
dll which is used to block the clicking of menu bar item.
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
static HWND s_hWndButton;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
switch (Reason) {
case DLL_PROCESS_ATTACH:
OutputDebugString(L"DLL attach function called11.\n");
break;
case DLL_PROCESS_DETACH:
OutputDebugString(L"DLL detach function called.\n");
break;
case DLL_THREAD_ATTACH:
OutputDebugString(L"DLL thread attach function called.\n");
break;
case DLL_THREAD_DETACH:
OutputDebugString(L"DLL thread detach function called.\n");
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) LRESULT __stdcall hookmethod(int code, WPARAM wParam, LPARAM lParam) {
TCHAR msgBuftext[65536];
TCHAR msgBufhandle[65536];
TCHAR msgBufhandletext[65536];
TCHAR msgBufwintext[2048];
if (code >= 0) {
MSG* cp = (MSG*)lParam;
int txtlen = GetWindowTextLengthW(cp->hwnd);
GetWindowText(cp->hwnd, msgBufhandletext, txtlen);
wsprintf(msgBufhandle, L"Handle %X", cp->hwnd);
wsprintf(msgBufwintext, L"Window Text %s", msgBufhandletext);
LPMSG msg = (LPMSG)lParam;
if (msg->message == WM_LBUTTONDOWN) {
OutputDebugString(msgBufwintext);
msg->message = WM_NULL;
}
}
return(CallNextHookEx(NULL, code, wParam, lParam));
}
For those who are interested, I would like to post the answer that I was able to implement. Basically , instead of listening to WH_GETMESSAGE, I changed the hook chain to WH_MSGFILTER. Reason because, it allows me to find the menu item id when I move the mouse over menu item and when the button up event happens, I can check the menu item id and disable mouse click by changing the message to WM_NULL. following is the working code sample. It also enable u to block the event if user is navigat
dll code
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <Winuser.h>
#include <Lmcons.h>
#include "nxlrunner.h"
WORD wMenuItemID;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
switch (Reason) {
case DLL_PROCESS_ATTACH:
OutputDebugString(L"DLL attach function called11.\n");
break;
case DLL_PROCESS_DETACH:
OutputDebugString(L"DLL detach function called.\n");
break;
case DLL_THREAD_ATTACH:
OutputDebugString(L"DLL thread attach function called.\n");
break;
case DLL_THREAD_DETACH:
OutputDebugString(L"DLL thread detach function called.\n");
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) LRESULT __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {
switch (code)
{
case MSGF_MENU: // message is for a menu
{
MSG* pMSG = (MSG*)lParam;
switch (pMSG->message)
{
case WM_MENUSELECT:
{
wMenuItemID = LOWORD(pMSG->wParam);
break;
}
case WM_LBUTTONDOWN:
{
break;
}
case WM_LBUTTONUP:
{
if (wMenuItemID == 10353){
wchar_t usernamew[UNLEN];
DWORD username_len = UNLEN + 1;
GetUserNameW(usernamew, &username_len);
MessageBoxW(NULL, usernamew, L"Title", MB_OK);
pMSG->message = WM_NULL;
}
break;
}
case WM_LBUTTONDBLCLK:
{
if (wMenuItemID == 10353){
pMSG->message = WM_NULL;
}
break;
}
case WM_KEYDOWN:
{
switch (pMSG->wParam)
{
case VK_RETURN:
{
if (wMenuItemID == 10353){
MessageBoxW(NULL, L"Message to user", L"Title.", MB_OK);
pMSG->message = WM_NULL;
}
break;
}
}
break;
}
case WM_KEYUP:
{
switch (pMSG->wParam)
{
case VK_RETURN:
{
if (wMenuItemID == 10353){
MessageBoxW(NULL, L"Message to user", L"Title", MB_OK);
pMSG->message = WM_NULL;
}
break;
}
}
break;
}
}
break;
}
}
return false;
}
windows hooking
system message hooks
Call MSG Filter function
msg structure
sample code
keyboard codes
sample code from internet

Didn't work on Windows 7, but it works on Windows 8 dll

I have two DLL files, A and B.
A needs B for setWindowsHookEx().
I use:
LoadLibrary(L"C:\\Sources\\TestDLL.dll") and GetProcAddress(hDll, "GetMsgProc")
When I try to run my program on Windows 7, GetProcAddress(hDll, "GetMsgProc") returns an error.
GetLastError() returns 122, but I think it not a good error code.
When I run my program on Windows 8 everything works.
When I change the function call in GetProcAddress(hDll, "foo")
typedef void(*foo)(); just creates message box
Everything works on Windows 7 and Windows 8.
I think my problem is __stdcall, but I don't find the solution.
DLL file A
typedef void(*foo)();
typedef LRESULT(_stdcall *LPGetMsgProc)(int nCode, WPARAM wParam, LPARAM lParam);
#define NOM_CLASSE_JAVA_TEST "Lcom/XXX/controller/fonctions/Fonctions;"
JNIEXPORT jboolean JNICALL Java_com_XXX_system_Jni_getVeille
(JNIEnv *env, jclass)
{
{
HINSTANCE hDll = (HINSTANCE)LoadLibrary(L"C:\\Sources\\TestDLL.dll");
CString str1("it ok");
if (!hDll)
{
CString str5("error1");
CString str4(GetLastError().ToString());
MessageBox(NULL, str4, str5, MB_ICONERROR);
return -1;
}
LPGetMsgProc pfnProc = (LPGetMsgProc)GetProcAddress(hDll, "GetMsgProc");
if (!pfnProc)
{
CString str5("error2");
CString str4(GetLastError().ToString());
MessageBox(NULL, str4, str5, MB_ICONERROR);
FreeLibrary(hDll);
return -1;
}
// Setup global hook
HHOOK hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)pfnProc, hDll, 0);
if (!hHook)
{
CString str5("hookeroor");
CString str4(GetLastError().ToString());
MessageBox(NULL, str4, str5, MB_ICONERROR);
FreeLibrary(hDll);
return -1;
}
while (TRUE)
{
// Check to see if any messages are waiting in the queue
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// Translate the message and dispatch it to WindowProc()
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// If the message is WM_QUIT, exit the while loop
if (msg.message == WM_QUIT)
break;
}
return true;
}
}
DLL file B
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <string>
#include <conio.h>
#include <tchar.h>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
#include <fstream>
#include <cstddef>
#include <cstdio> //std::remove
#include <vector>
#pragma comment(lib, "user32.lib")
extern "C" _declspec(dllexport) void foo(void)
{
MessageBox(NULL, (LPCTSTR)"ok", (LPCTSTR)"ok", MB_ICONERROR);
}
//============================================================================
extern "C"
{
_declspec(dllexport) LRESULT _stdcall GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MessageBox(NULL, (LPCTSTR)"ok", (LPCTSTR)"ok", MB_ICONERROR);
nCode = 0;
wParam = NULL;
lParam = NULL;
}
}
//============================================================================
I run my program on Windows 8 64 bit and Windows 7 32 bit.
I run Dependency Walker and I found the name GetProcAddress(hDll, "_GetMsgProc#12");, but my program won't work.
The code or the compiler then must have Windows 8 and more recent code that is not compatible with Windows 7 or older.

WinApi CreateDialog returns error 715

I'm trying to get this simple windows dialog to spawn but as soon as I start it it reports "Error x715" which means hDialog was not correctly made in the int WINAPI WinMain() function. It compiles just fine.
I'm working in Visual Studio 2010 and it's a "Visual C++ -> Empty Project" project.
This is the full main.cpp file, which is the only file in the project:
#include "windows.h"
#define DLG_MAIN 200 // ID for dialog
#define DLG_ICON 30000 // IDs for icons
#define DLG_ICON_S 30000
#define IDC_QUIT 1011 // ID for "quit"-button
#define IDC_INFO 2000 // ID for "info"-button
#define ID_TIMER 1 // ID for timer
#define IDC_STATIC -1 // ID for all labels
#define TIMER_INTERRUPT 500 // timer msg interval in msec
HINSTANCE TheInstance = 0; // instance handle of this program
// Our main function
void lalala(HWND hwnd)
{
/*Doesn't do anything yet.*/
}
// Windows passes messages to application windows to indicate "something"
// needs to be done
BOOL CALLBACK DialogProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
// set the time to generate a timer message (WM_TIMER)
SetTimer(hwnd, ID_TIMER, TIMER_INTERRUPT, NULL);
return TRUE;
case WM_TIMER:
// a timer msg was received so call our main function!
lalala(hwnd);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_INFO:
// the info button on the window was pressed
MessageBox(hwnd, "<show some info>", "The Jonas Brothers are way better than Nick Cave ever was.", MB_OK);
return TRUE;
case IDC_QUIT:
// the quit button on the window was pressed
PostQuitMessage(0);
return TRUE;
}
return TRUE;
case WM_DESTROY:
// this app is about to be closed so kill the timer
KillTimer(hwnd, ID_TIMER);
PostQuitMessage(0);
return TRUE;
case WM_CLOSE:
// destroy the window
DestroyWindow (hwnd);
return TRUE;
}
return FALSE;
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
TheInstance = hInst;
HWND hDialog = 0;
hDialog = CreateDialog (hInst, MAKEINTRESOURCE (DLG_MAIN), 0, (DLGPROC)DialogProc);
if (!hDialog)
{
char buf [100];
wsprintf (buf, "Error x%x", GetLastError ());
MessageBox (0, buf, "CreateDialog", MB_ICONEXCLAMATION | MB_OK);
return 1;
}
HICON hIcon = LoadIcon (TheInstance, MAKEINTRESOURCE (DLG_ICON));
SendMessage (hDialog, WM_SETICON, WPARAM (TRUE), LPARAM (hIcon));
hIcon = LoadIcon (TheInstance, MAKEINTRESOURCE (DLG_ICON_S));
SendMessage (hDialog, WM_SETICON, WPARAM (FALSE), LPARAM (hIcon));
MSG msg;
int status;
while ((status = GetMessage (&msg, 0, 0, 0)) != 0)
{
if (status == -1) return -1;
if (!IsDialogMessage (hDialog, &msg))
{
TranslateMessage ( &msg );
DispatchMessage ( &msg );
}
}
return msg.wParam;
}
Can anyone tell me why it fails at hDialog = CreateDialog (hInst, MAKEINTRESOURCE (DLG_MAIN), 0, (DLGPROC)DialogProc); ?
Error 0x715 is ERROR_RESOURCE_NAME_NOT_FOUND, which you get when it fails to find the dialog with the name that you supplied, in the resource section. Instead of declaring the macros for each resources, just use #include "resource.h"