Windows 3.11 WH_MOUSE_LL equivalent? - c++

I'm trying to develop a little helper tool to enable mouse integration for Windows 3.11 in VMWare Fusion since VMWare does not provide tools for this platform.
I can already read the mouse position in my application using the WH_MOUSE hook using the following code:
// VMOUSE - Hook global mouse to escape VM automatically
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "smprintf.h"
HHOOK hMouseHook;
LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
MOUSEHOOKSTRUCT *pMouseStruct = (MOUSEHOOKSTRUCT*)lParam;
printf("Mouse position X = %d, Y = %d\n", pMouseStruct->pt.x, pMouseStruct->pt.y);
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
hMouseHook = SetWindowsHookEx(WH_MOUSE, mouseProc, hInstance, NULL);
MessageBox(NULL, "Hello World", "Title", MB_OK);
return 0;
}
I understand that modern Win32 provides a WH_MOUSE_LL hook to detect mouse movement outside of the application itself and I was wondering if such a hook was available for Windows 3.11.
The communication between the host and the VM is a whole other thing, currently I'm planning to do this via winsock and trigger the keystroke on the host.
It would be amazing if anyone actually knows how to do this.
Thank you

Related

Make a event for a mouse button even if application is minimized

I want to make an application that responds to a mouse button so I done this:
case WM_LBUTTONDOWN:
MessageBox(
NULL,
(LPCWSTR)L"HALLOOOO",
(LPCWSTR)L"Worked",
MB_ICONASTERISK | MB_OK | MB_DEFBUTTON2
);
break;
but the problem is that this only works if the user clicks on the window and I want it to work even with the window minimized
this work even if the application is minimized
GetKeyState(VK_LBUTTON);
but if I put this in a loop if I press it once it will detect 1 million times because it will just check if the key is down and if I add delay using Sleep(250) it may work but sometimes it will not detect anything even if the user pressed the key
I want my app to be able to detect if a key is pressed even if it's minimized how can I do this?
Since you already have a window, call SetWindowsHookEx with WH_MOUSE_LL.
The API is documented here and the parameters are explained.
HHOOK SetWindowsHookExW(
[in] int idHook,
[in] HOOKPROC lpfn,
[in] HINSTANCE hmod,
[in] DWORD dwThreadId
);
The lpfn hook procedure can be defined as follows:
HWND hmain_window;
HHOOK hhook;
LRESULT CALLBACK mouse_proc(int code, WPARAM wparam, LPARAM lparam)
{
if (code == HC_ACTION && lparam)
{
if (wparam == WM_LBUTTONDOWN)
{
//MOUSEHOOKSTRUCT* mstruct = (MOUSEHOOKSTRUCT*)lparam;
static int i = 0;
std::wstring str = L"mouse down " + std::to_wstring(i++);
SetWindowText(hmain_window, str.c_str());
}
}
return CallNextHookEx(hhook, code, wparam, lparam);
}
int APIENTRY wWinMain(HINSTANCE hinst, HINSTANCE, LPWSTR, int)
{
...
RegisterClassEx(...);
hmain_window = CreateWindow(...);
hhook = SetWindowsHookEx(WH_MOUSE_LL, mouse_proc, hinst, 0);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(hhook);
return 0;
}
You can try SetWindowsHookEx with parameter WH_MOUSE_LL or WH_MOUSE.
This article shows how to install a keyboard hook. You can replace WH_KEYBOARD with WH_MOUSE to install a mouse hook and use this document to handle the callback.

how to set image in dialogbox in c++ win32 API?

i have developing a C++ Api project.
i will use dialogboxparam to create a dialogbox...
i done to create and set the textbox,labels and buttons...
its work fine...
now i want to add a image in the top of the dialogbox...
i did use this code in WM_INITDIALOG:
HBITMAP hImage= (HBITMAP)LoadImage(NULL,L"C:\\WINDOWS\\system32\\BMA-Images\\login-header",IMAGE_BITMAP,LR_DEFAULTSIZE ,LR_DEFAULTSIZE ,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
SendMessage(_hwnd,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hImage);
But it didnt work...
Can anyone help to resolve this...
Thanks in advance
Sonu
The easiest way is to override the WM_PAINT for the window and paint the bitmap at that point (between the BeginPaint and EndPaint) calls
There is an MFC based example here:
http://www.programmersheaven.com/mb/mfc_coding/113034/113034/how-do-i-set-a-background-picture-in-a-dialog-box-/
When processing the WM_INITDIALOG message use HWND hImageCtl = GetDlgItem(_hwnd, <image-control-resource-id>) to get the handle of the image-control (this assumes _hwnd is the handle to the dialog itself).
Then use hImageCtl to send the STM_SETIMAGE message to.
This works for years, since Windows 98 for me:
//globals
HBRUSH hbr;
PAINTSTRUCT wcd;
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam )
{
switch( msg ) {
case WM_PAINT:
if (GetUpdateRect(hWnd,r,0)) {
BeginPaint(hWnd,&wcd);
if (wParam == NULL) FillRect(wcd.hdc,&wcd.rcPaint,hbr);
EndPaint(hWnd,&wcd);
}
break;
case WM_COMMAND:
///your code
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int Show)
{
ghInstance = hInstance;
//Prepare brush for background
hbr=CreatePatternBrush(LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BGROUND)));
///your code
DialogBox(hInstance,"MAIN", NULL,(DLGPROC)MainWndProc);
///your code
return(FALSE);
}
IDB_BGROUND - id of image resource, linked in.

Common Dialogs DLL cannot be loaded manually

Hello everyone,
I am making a VC++ 2008 project in pure Win32 API which uses common controls. Now the problem that I am facing is if I explicitly link to the comctl32.dll(version 6.0.) in the WinSXS folder using the LoadLibrary API function, my main window does not even display. But if I use the #pragma comment in my code as such -:
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
and add the comctl32.lib to my project dependencies then run it then I get my expected output. But if I link manually to the comctl32.dll in the WinSXS using LoadLibrary API function and then get the procedure address of InitCommonControls using the GetProcAddress Api function and then call it my main window does not even display. Why is this happening?
By definition I should be able to load my dll manually locate the required procedure that I want to use and execute it, but for some reason this is not happening here.
this is the code that I am using -:
#include <Windows.h>
#include <CommCtrl.h>
#include "resource.h"
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DialogFunc(HWND, UINT, WPARAM, LPARAM);
char szWinName[]="Timer Main Window";
HWND hDlg=NULL;
HINSTANCE hInst;
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst,
LPSTR lpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
HMODULE hmod=NULL;
void (*InitCommonControls)(void)=NULL;
wndclass.cbSize=sizeof(WNDCLASSEX);
wndclass.hInstance=hThisInst;
wndclass.lpszClassName=szWinName;
wndclass.lpfnWndProc=WindowFunc;
wndclass.style=0;
wndclass.hIcon=LoadIcon(hThisInst,MAKEINTRESOURCE(IDI_ICON1));
wndclass.hIconSm=LoadIcon(hThisInst,MAKEINTRESOURCE(IDI_ICON2));
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.lpszMenuName=NULL;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH) GetStockObject(LTGRAY_BRUSH);
if(!RegisterClassEx(&wndclass)) return 0;
/*Initialize the common controls for WinXP look and feel*/
hmod=LoadLibrary("C:\\WINDOWS\\WinSxS\\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.6028_x-ww_61e65202\\comctl32.dll");
if (!hmod)
{ MessageBox(NULL,"dll not loaded","error",MB_ICONERROR);
}
InitCommonControls=(void (*)(void)) GetProcAddress(hmod,
"InitCommonControls");
if(InitCommonControls==NULL){
MessageBox(NULL,"no entry point","error",MB_ICONERROR);
}
(*InitCommonControls)();
//FreeLibrary(hmod);
//hmod=NULL;
hInst=hThisInst;
hwnd=CreateWindow(
szWinName,
"Auto Timer (Work in progress)",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hThisInst,
NULL
);
while(GetMessage(&msg, NULL, 0, 0)>0)
{ if (!hDlg||!IsDialogMessage(hDlg,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wparam,
LPARAM lparam)
{
switch(message){
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
hDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_FORMVIEW),
hwnd,(DLGPROC)DialogFunc);
break;
default:
return DefWindowProc(hwnd,message,wparam,lparam);
}
return 0;
}
BOOL CALLBACK DialogFunc(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam)
{
switch(message)
{
case WM_INITDIALOG:
SendMessage(hwnd,WM_SETICON, ICON_SMALL ,
(LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON2)));
break;
case WM_CTLCOLORSTATIC:
return (INT_PTR)GetStockObject(WHITE_BRUSH);
case WM_CLOSE:
DestroyWindow(hwnd);
hDlg=NULL;
PostQuitMessage(0);
return TRUE;
}
return FALSE;
}
If anyone wants the entire project please give me your mail id and I will send the entire project to them. I want to know exactly why this is happening not whether I should do it or not.Thank You.
The working case
Your manifest refences the Microsoft.Windows.Common-Controls assembly. This assembly is a collection of one or more DLLs and COM objects, it is not a .Net assembly. When your application is launched Windows creates an activation context. Any references to a DLL or COM object that is described in the assembly are redirected to the requested version. The activation context remains active during calls into comctl32.dll, so any calls it makes to DLLs or COM objects will also be redirected.
The not-working case
You load a specific version of comctl32.dll from \Windows\Sxs\. This references other DLLs or COM objects but, in the absence of an activation context, the wrong ones are loaded. And your application doesn't work.
Conclusion
I don't know if this is the specific problem in your case, but in general anything that lives in \Windows\Sxs is intended to run in a particular activation context, and you can't expect it to work outside of that context. Even if it did happen to work, it might break in the future. Don't do this.

How do I correctly set the entry point for an exe in Visual Studio?

I have set the entry point to WinMain but when I run the app it starts and doesn't display, I then have to shut it with task manager. Here's the code upto WinMain() :
#include <Windows.h>
// forward declarations
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// The entry point into a windows program
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int windowStyle )
{
....
I'm not experienced in C++, and I don't know what this is doing, except making my exe smaller, which is what I'm trying to achieve.
edit : What I'm trying to do is create a very small window exe to understand how demo coder's work. So I'm thinking of creating a small c++ window app that provides a window handle to which I can attach SlimDX (if i can statically link the final c++ dll to a C# app, but I'm not there yet) I have my BasicWindow.exe down to 6,656 bytes. So I'm experimenting with anything I can find to get that size down to <3k.
[2012.Jan.10] Well I've had some success by rebuilding minicrt (available from http://www.benshoof.org/blog/small-programs/) under VS2010 and adding it as an additional dependency. I couldn't Ignore All Default Libraries as suggested, but I now have a Windowed application with an exe size of 4,096 bytes. I'd say that's some significant success. I'm within striking distance now. Every reduction from here on in, is more room for SlimDX. I'm pretty happy considering the only c++ apps I've ever written are console apps and a basic window :) I've been lucky I know !
A typical application should not mess up with Entry point setting of linker. Entry point should be set on a function included in the standard runtime library (which is wWinMainCRTStartup for unicode application for windows subsystem). This function does stuff like the proper initialization of CRT and creation of global objects. By rerouting entry point to your WinMain you will get undefined behavior unless you know precisely what you are doing and somehow implementing CRT initialization in your own WinMain. In my opinion the resulting size decrease will be negliable and the whole affair is hardly worth the risk.
When you set the entry point to WinMain, Windows doesn't give your program a console window, because WinMain is for programs with GUIs that don't need a console window. Your program is indeed running, though with no GUI you don't see anything happen.
I had the same issue. I wasn't satisfied with the answer marked here. So, I started digging in more and found that WS_VISIBLE was missing from CreateWindowEx function.
WS_OVERLAPPEDWINDOW with WS_VISIBLE makes the code work perfectly.
And regarding the file size, I was able to bring down the size of the code for x64 build to 3,072 bytes 1,600 bytes using Visual Studio Community Edition 2013 running on Windows 7 Ultimate SP1 x64. All this, without using minicrt.lib, you mentioned above.
Here's a screenshot of the executable properties.
For reference, here is the full program :
#include <Windows.h>
// forward declarations
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // WindowProcedure function
// The entry point into a windows program
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int windowStyle )
{
// create and register a local window class > exit on failure
WNDCLASSEX wcx;
HINSTANCE zhInstance = GetModuleHandle(NULL);
wcx.cbSize = sizeof(WNDCLASSEX); // size of structure
wcx.style = CS_HREDRAW | CS_VREDRAW; // redraw if size changes
wcx.lpfnWndProc = WndProc; // window procedure
wcx.cbClsExtra = 0; // no extra class memory
wcx.cbWndExtra = 0; // no extra windows memory
wcx.hInstance = zhInstance; // handle to instance (owner)
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); // predefined icon
wcx.hCursor = LoadCursor (NULL, IDC_ARROW); // predefined arrow
wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//(HBRUSH) (COLOR_WINDOW + 1);// white background brush
wcx.lpszMenuName = NULL; // name of menu resource
wcx.lpszClassName = TEXT("BasicWindow"); // name of window class
wcx.hIconSm = (HICON)LoadImage(zhInstance, // small class icon
MAKEINTRESOURCE(5),
IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CYSMICON),
LR_DEFAULTCOLOR);
if (!RegisterClassEx(&wcx))
{
MessageBoxA(0, "Error registering window class!","Error",MB_ICONSTOP | MB_OK);
DWORD result = GetLastError();
return 0;
}
// create window > exit on failure
HWND hwnd; // the window handle
hwnd = CreateWindowEx(
WS_EX_STATICEDGE,
wcx.lpszClassName,
TEXT("Basic Window"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
320,
240,
NULL,
NULL,
zhInstance,
NULL);
if (hwnd == NULL)
{
MessageBoxA(0,"Error creating window!","Error",MB_ICONSTOP | MB_OK);
return 0;
}
// show window
ShowWindow(hwnd, SW_MAXIMIZE);
// send a WM_PAINT message to the window
UpdateWindow(hwnd);
// enter message loop, break out of loop if there is an error (result = -1)
MSG msg; // for storing the windows messages
int status; // for storing the status of the windows message service where -1 = error, 0 = WM_QUIT, n = any other message)
while ((status = GetMessage(&msg,(HWND) NULL,0,0)) != 0 && status != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
UNREFERENCED_PARAMETER(lpCmdLine);
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}

Win API: How to catch every message from user input?

I want to catch:
Window resize/move/minimize/maximize/close messages.
Mouseclicks and keyboard presses.
When any program was executed by the user either pressing enter or dblclick. (if possible?)
This should work the same way as the keylock programs works: if you do some event, i can decide via my program will i let Windows handle it, or do i handle it, or both.
How can i do this?
As Hans Passant pointed out, you need the SetWindowsHookEx function.
In the link all possible hooks are explained in detail and the hook functions you need to implement are as well. Here is a small example, how to install a global hook that will process messages, after they are processed by the window.
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
HHOOK msgHook = SetWindowsHookEx(WH_CALLWNDPROCRET, msgHook, hInstance, 0);
if(msgHook == NULL){
//Error handling here
cout << "Failed to set hook";
}
else{
//Hook has been set and will automatically be removed, when your application exits.
}
//A clean shutdown should always unhook everything it has installed
UnhookWindowsHookEx(msgHook);
return 0;
}
You can look up the hook functions definition in the MSDN, but it could look like this:
LRESULT CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam){
CWPRETSTRUCT* theMessage = (CWPRETSTRUCT*)lParam;
//now you can read all message parameters and the return value
//...
//Always return by calling the next hook in the chain
return CallNextHookEx(0, nCode, wParam, lParam);
}
The other hooks that you want to install follow the same principle.
See also
Hooks Overview
Using Hooks