Simple if comparison doesn't work with char - c

I am creating a DLL to check when the user presses the close button on the application window, it works fine, then I want to do it so that when _text global variable is empty, no message will be shown.
I can't understand why a simple if (_text != "") doesn't work... am I doing something wrong?
#include <windows.h>
#define export extern "C" __declspec (dllexport)
WNDPROC GameWndProc = NULL;
HWND GameHwnd = NULL;
double _button_result = 0;
char* _text;
char* _title;
LRESULT CALLBACK SubClassWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_CLOSE:
if (_text != "") {
if (MessageBox(GameHwnd, (LPSTR)_text, (LPSTR)_title, MB_YESNO|MB_APPLMODAL) == IDYES) {
_button_result = 1;
return 0;
} else {
return 0;
}
}
_button_result = 1;
return 0;
break;
}
return CallWindowProc(GameWndProc, hwnd, uMsg, wParam, lParam);
}
export double _window_check_close_init(double window_handle, char* _msg_text, char* _msg_title)
{
GameHwnd = (HWND)(int)window_handle;
GameWndProc = (WNDPROC)SetWindowLongPtr(GameHwnd, GWL_WNDPROC, (LONG)SubClassWndProc);
_text = _msg_text;
_title = _msg_title;
if (!GameWndProc) {
return 0;
}
return 1;
}
export double _window_check_close()
{
if (_button_result == 1) {
_button_result = 0;
return 1;
} else {
return 0;
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_DETACH) {
if (IsWindow(GameHwnd) && GameWndProc) {
SetWindowLongPtr(GameHwnd, GWL_WNDPROC, (LONG)GameWndProc);
}
}
return TRUE;
}

You're checking if the pointer _text is equal to the empty string, not if the string pointed to by _text is equal to the empty string. You probably want to do something like:
if (strlen(_text) !=0)
... rest of your code...

Use strcmp() to compare strings:
if (strcmp(_text, "") != 0) {
}

Just to clarify the difference between pointers and contents of the location to which pointer points:
char* _text : The variable 'text' is a pointer. If you look at it in a debugger it would hold a hex value which would be a memory address. In your case _text holds the address of the string _msg_text
_text != "" : You are comparing two pointers, not their contents. "" in this statement is returning the location of the null string which would again be some hex value which is a memory address.
What you need to do is compare the contents of _text with the null string ""
The above answers are correct.

Related

Custom WM_APP message isn't posted in the message queue

I am trying to send a custom message (WM_APP + 1) when WM_SIZE is send to the window procedure. I want to be able to catch it from an other function using PeekMessage and do somethings. But when I test it the messages seem to not be send to the queue. Adding some printf statements shows me that it goes to the window procedure. The weird thing is that when I step through the code in the debugger it works fine but when I'm running normally, it goes back to not working.
Working example program with the problem, resize the window to test:
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")
#define OBG_EVENT_QUIT 0
#define OBG_EVENT_RESIZE 1
#define OBG_EVENT_NO -1
#define OBG_EVENT_UNKNOWN -2
//user defined event
#define OBG_WM_RESIZE (WM_APP + 1)
typedef union
{
int type;
struct
{
int type;
int width;
int height;
} resizeEvent;
} obg_event;
LRESULT CALLBACK obgpf_DefaultWindowCallback(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
switch(message)
{
case WM_CLOSE:
{
PostMessageA(window, WM_QUIT, 0, 0);
} break;
//this should be handled by OBGGetEvent
case OBG_WM_RESIZE:
{
printf("MESSAGE WENT THROUGH. DON'T WANT THIS\n");
} break;
case WM_SIZE:
{
PostMessageA(window, OBG_WM_RESIZE, wParam, lParam);
} break;
default:
{
result = DefWindowProc(window, message, wParam, lParam);
} break;
}
return result;
}
int OBGGetEvent(obg_event *event)
{
int moreMessages = 0;
MSG message;
if(PeekMessage(&message, 0, 0, 0, PM_REMOVE))
{
moreMessages = 1;
switch(message.message)
{
case WM_QUIT:
{
event->type = OBG_EVENT_QUIT;
} break;
case OBG_WM_RESIZE:
{
event->type = OBG_EVENT_RESIZE;
event->resizeEvent.type = OBG_EVENT_RESIZE;
event->resizeEvent.width = LOWORD(message.lParam);
event->resizeEvent.height = HIWORD(message.lParam);
} break;
default:
{
event->type = OBG_EVENT_UNKNOWN;
TranslateMessage(&message);
DispatchMessage(&message);
} break;
}
}
else
{
event->type = OBG_EVENT_NO;
}
return moreMessages;
}
int main()
{
HINSTANCE instance = GetModuleHandleA(0);
WNDCLASSEX windowClass = {0};
windowClass.cbSize = sizeof(windowClass);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = obgpf_DefaultWindowCallback;
windowClass.hInstance = instance;
windowClass.lpszClassName = "testClass";
windowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
windowClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
windowClass.hCursor = LoadCursorA(0, IDC_ARROW);
HWND window;
if(RegisterClassEx(&windowClass))
{
window = CreateWindowEx(0,
windowClass.lpszClassName,
"test window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
300,
0,
0,
instance,
0);
if(window)
{
int appIsRunning = 1;
obg_event event = {0};
event.type = -1;
while(appIsRunning)
{
while(OBGGetEvent(&event))
{
if(event.type == OBG_EVENT_QUIT)
{
printf("event quit\n");
appIsRunning = 0;
break;
}
else if(event.type == OBG_EVENT_RESIZE)
{
printf("window resized: width %d height %d\n", event.resizeEvent.width, event.resizeEvent.height);
}
}
Sleep(33);
}
}
else
{
printf("window error\n");
}
}
else
{
printf("windowClass error\n");
}
return 0;
}
I tried doing this with SendMessage instead of PeekMessage but the same thing happened. Not sure what I'm missing or misunderstanding but any help is appreciated!
EDIT: added a complete working program that reproduces the problem
Thank you for the example code.
The behaviour you're seeing is because when the window is being resized using the mouse, the OS enters a modal message loop to process mouse input. During this loop, your message loop doesn't run - which means your PeekMessage() and the special message handling doesn't run either. Instead, messages are simply dispatched as normal to your window procedure.
There are two solutions that come to mind immediately but how you deal with this really depends on the design of your program and why you want to process size events in this way.
The first idea I had is to keep track of whether you're in a modal sizing loop or not, and defer posting the notification message until the loop is finished. An example of how to do that using your provided window procedure is below.
The second solution is to simply call your resize event handler directly whenever you get WM_SIZE (or, if you must go through the event system, put the handler for it in the window procedure rather than using PostMessage).
Example code for the first suggestion:
LRESULT CALLBACK obgpf_DefaultWindowCallback(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
static bool fResized = false;
static bool fInSizeLoop = false;
switch(message)
{
case WM_CLOSE:
{
PostMessageA(window, WM_QUIT, 0, 0);
} break;
//this should be handled by OBGGetEvent
case OBG_WM_RESIZE:
{
printf("MESSAGE WENT THROUGH. DON'T WANT THIS\n");
} break;
case WM_SIZE:
{
if (fInSizeLoop) // in modal size loop, defer notification
fResized = true;
else
PostMessageA(window, OBG_WM_RESIZE, wParam, lParam);
} break;
case WM_ENTERSIZEMOVE:
fInSizeLoop = true; // begin modal size loop
break;
case WM_EXITSIZEMOVE:
fInSizeLoop = false; // left modal size loop
// post resize notification now
if (fResized) {
RECT rc;
GetClientRect(window, &rc);
PostMessageA(window, OBG_WM_RESIZE, 0, MAKELPARAM(rc.right - rc.left, rc.bottom - rc.top));
fResized = false;
}
break;
default:
{
result = DefWindowProc(window, message, wParam, lParam);
} break;
}
return result;
}
(sorry, this is C++ code and I just noticed you had tagged as C - but the principle is the same).

How to block printing functionality(CTRL + P) on windows text editors?

I want to block printing functionality(CTRL + P) on windows platform for specific applications. I am doing it using keyboard hook. I am able to detect CTRL + P but I am not able to stop it. I am returning from hook procedure in case of CTRL + P but application still receives this message and process printing.
LRESULT __declspec(dllexport)__stdcall CALLBACK KeyboardProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
FILE* f1;
static WPARAM wPrevParam;
if (((DWORD)lParam & 0x40000000) && (HC_ACTION == nCode))
{
if ((wParam == VK_SPACE) || (wParam == VK_RETURN) || (wParam == VK_CONTROL) || (wParam >= 0x2f) && (wParam <= 0x100))
{
char ch;
f1 = fopen("d:\\report.txt", "a+");
if (wParam == VK_CONTROL)
{
if (wPrevParam == 0x50)// 0x50 = P
{
const char* text = "CTRL-P detected.";
fwrite(text, strlen(text), 1, f1);
fclose(f1);
wParam = 0;
lParam = 0;
return 1;
}
const char *text = "CTRL";
fwrite(text, strlen(text), 1, f1);
fprintf(f1, "%02X\n", (unsigned char)wParam);
}
else
{
wPrevParam = wParam;
}
fclose(f1);
}
}
LRESULT RetVal = CallNextHookEx(hkb, nCode, wParam, lParam);
return RetVal;
}
I want to block printing functionality(CTRL + P) on windows platform
for specific applications. I am doing it using keyboard hook. I am
able to detect CTRL + P but I am not able to stop it.
This blocks [Ctrl] + "P" in a WH_KEYBOARD_LL hook... but won't prevent printing by [File] [Print] or other way of course... =>
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
DWORD dwKey = 0;
if (HC_ACTION == nCode)
{
KBDLLHOOKSTRUCT *pkbdll = (KBDLLHOOKSTRUCT*)lParam;
dwKey = pkbdll->vkCode;
BOOL bCtlDown = GetKeyState(VK_CONTROL) < 0;
if (bCtlDown && dwKey == 'P')
{
Beep(6000, 10);
return 1;
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
Windows application to block CTRL + P using WH_KEYBORAD_LL hook works. So working code snippet will be as follows:
#include<fstream>
#include<windows.h>
using namespace std;
ofstream out("logs.txt", ios::out);
LRESULT CALLBACK keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
static bool controlPressed = false;
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)(lParam);
if (wParam == WM_KEYDOWN)
{
if (p->vkCode == VK_LCONTROL || p->vkCode == VK_RCONTROL)
{
controlPressed = true;
}
else if (char(tolower(p->vkCode)) == 'p' && true == controlPressed)
{
out << "<CONTROL + P Detected>";
return 1;
}
else
{
controlPressed = false;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HHOOK keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL,
keyboardHookProc,
hInstance,
0
);
MessageBox(NULL, TEXT("Press OK to stop blocking of printing."), TEXT("Information"), MB_OK);
out.close();
return 0;
}

Global keyboard hook in C using DLL doesn't work

I tried to do global keyboard hooking in C and got in trouble.
My purpose is that when I type F2 key or Ctrl key, some lines will be printed to check whether it works or not, and if I press the q key, it will stop hooking.
To test the whole code, I've used printf in some parts.
I have no idea how to figure out this problem, but really want to solve it.
.cpp code:
#include "stdio.h"
#include "conio.h"
#include "windows.h"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"
typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();
void main() {
HMODULE hDll = NULL;
PFN_HOOKSTART HookStart = NULL;
PFN_HOOKSTOP HookStop = NULL;
char ch = 0;
// load Dll
hDll = LoadLibrary(L"HookTest.dll");
if (hDll == NULL) {
printf("load fail \n");
return;
}
else {
printf("load success \n");
}
HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);
HookStart();
printf("press 'q' to quit!\n");
// if user push 'q' key, HookStop
while (1) {
if (_getch() == 'q') {
break;
}
printf("Test Typing \n");
}
HookStop();
FreeLibrary(hDll);
}
.dll code:
#include <stdio.h>
#include <windows.h>
#pragma data_seg(".kbdata")
HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.kbdata,RWS")
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
g_hInstance = hinstDLL;
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" {
LRESULT __declspec(dllexport) CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
printf("Test 1 --- KeyboardProc sucess \n");
if (nCode >= 0) {
printf("Test 2 --- \n");
if (wParam == VK_F2) {
printf("F2 Key Typed ");
}
else if (wParam == VK_CONTROL) {
printf("Ctrl Key Typed ");
}
else {
printf("Other Key Typed");
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
}
extern "C" __declspec(dllexport) void HookStart() {
g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
printf("Test 3 --- HookStart Call \n");
}
extern "C" __declspec(dllexport) void HookStop() {
printf("Test 4 --- HookStop Call \n");
if (g_hHook) {
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
}

How can I center a Dialog Box over main program window position?

I've got this code to open an InputBox defined on a DLL that get HMODULE that I save on hInstance variable when main program calls. How can I center it over the main program window?
It occurs that doesn't work and shows the DialogBox on top left on Screen or on top left of program window randomly.
#include <windows.h>
#include "resource.h"
char IB_res[10];
double defaultValue = 0;
BOOL CALLBACK InputBox_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
if (defaultValue != -1)
SetDlgItemText(hwnd, IDC_EDIT, (LPCSTR)(my_printf("%f", defaultValue).c_str()));
else
SetDlgItemText(hwnd, IDC_EDIT, (LPCSTR)"");
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
if (!GetDlgItemText(hwnd, IDC_EDIT, IB_res, 10))
*IB_res = 0;
case IDCANCEL:
EndDialog(hwnd, wParam);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
DWORD processId;
HWND hwndParent;
BOOL CALLBACK enumWindowsProc(HWND hwnd, LPARAM lParam)
{
DWORD procid;
GetWindowThreadProcessId(hwnd, &procid);
if (procid == processId)
hwndParent = hwnd;
return TRUE;
}
HINSTANCE hInstance;
const char* InputBox(double def_value)
{
defaultBetValue = def_value;
processId = GetCurrentProcessId();
EnumWindows(enumWindowsProc, 0);
INT_PTR ret = DialogBox(hInstance, MAKEINTRESOURCE(IDD_IB), hwndParent, InputBox_WndProc);
DWORD error = GetLastError();
if (ret != IDOK)
*IB_res = 0;
return IB_res;
}
From:
http://msdn.microsoft.com/en-gb/library/windows/desktop/ms644996(v=vs.85).aspx
case WM_INITDIALOG:
// Get the owner window and dialog box rectangles.
if ((hwndOwner = GetParent(hwndDlg)) == NULL)
{
hwndOwner = GetDesktopWindow();
}
GetWindowRect(hwndOwner, &rcOwner);
GetWindowRect(hwndDlg, &rcDlg);
CopyRect(&rc, &rcOwner);
// Offset the owner and dialog box rectangles so that right and bottom
// values represent the width and height, and then offset the owner again
// to discard space taken up by the dialog box.
OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
OffsetRect(&rc, -rc.left, -rc.top);
OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
// The new position is the sum of half the remaining space and the owner's
// original position.
SetWindowPos(hwndDlg,
HWND_TOP,
rcOwner.left + (rc.right / 2),
rcOwner.top + (rc.bottom / 2),
0, 0, // Ignores size arguments.
SWP_NOSIZE);
if (GetDlgCtrlID((HWND) wParam) != ID_ITEMNAME)
{
SetFocus(GetDlgItem(hwndDlg, ID_ITEMNAME));
return FALSE;
}
return TRUE;

why is this function failing?

I am trying to understand windows hooks by writing a few keyboard hooks.
I have a function:
bool WriteToFile(WPARAM keyCode, char * fileName)
{
ofstream fout("filename");
if(fout.is_open())
{
if(keyCode>=0x030 && keyCode<0x039)
fout<< (keyCode - 0x030);
fout.close();
return true;
}
else fout.close();
return false;
}
...that i try to call from here but it almost always fails. Why?
LRESULT CALLBACK KbHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode > 0)
{
WriteToFile(wParam,"log.txt"); //this function always fails . Why
}
else return CallNextHookEx(hCurrentHook, nCode, wParam, lParam);
}
I think it's because you're trying to open a file called “filename”, rather than using whatever filename was provided. I assume you're writing a keylogger. It should read:
bool WriteToFile(WPARAM keyCode, char * fileName)
{
// cause output to go to the end of the file by using ios_base::app
ofstream fout(fileName, ios_base::app);
if(fout.is_open())
{
if(keyCode>=0x030 && keyCode<0x039)
fout<< (keyCode - 0x030);
fout.close();
return true;
}
else fout.close();
return false;
}

Resources