There is a racing game, I need to collect telemetry and statistics. And to add an additional HUD
I compiled the Detours. And could make the hook to change the name of the application window.Like:
LRESULT (WINAPI * TrueSendMessageW)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) = SendMessageW;
__declspec(dllexport) LRESULT WINAPI MySendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == WM_SETTEXT)
return TrueSendMessageW(hWnd, Msg, wParam, (LPARAM)L"new name window");
return TrueSendMessageW(hWnd, Msg, wParam, lParam);
}
...
And run it with withdll.exe. All ok.
But I cannot figure out how to intercept direct3d. With the help of API monitor, I found that the program uses Microsoft.Xna.Framework.Graphics.dll IDirect3DDevice9::SetTexture
Can someone tell how to get this texture? In general, I would like to get something like link
Detour intercepts OS API calls and Direct3D is implemented via COM object concept. You probably can intercept the very first step of D3D device object creation but after this point you'll have to deal with COM object interfaces and Detour won't be helping you.
Related
I need to get the current WndProc with its messages and configuration and add my own code to it. Why do I need this? Because I'm working under an IDE that defines a window (and its children controls) with a WndProc, and I need to modify it because It contains all the actions related with every control. If I point a control to a custom WndProc the control loses all the actions and configuration set by the IDE. Suggestions?
Scheme:
HWND button; //My Button
LONG_PTR wndProc = GetWindowLongPtr(button, GWL_WNDPROC); //Getting the WndProc
wndProc -> Get this `WndProc` source code
LRESULT CALLBACK WndProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
wndProc (all the data);
+ my messages
}
You can't get source code of "old" WndProc of course, but you can call it using CallWindowProc() in your new wnd proc. Check out this article:
When you subclass a window, it's the original window procedure of the window you subclass you have to call when you want to call the original window procedure
Quote:
... your subclass function should go something like this:
wndProcOrig =
(WNDPROC)SetWindowLongPtr(hwndButton, GWLP_WNDPROC, (LONG_PTR)SubclassWndProc);
LRESULT CALLBACK SubclassWndProc(HWND hwnd, UINT wm, WPARAM wParam, LPARAM lParam)
{
switch (wm) {
...
default:
return CallWindowProc(wndprocOrig, hwnd, wm, wParam, lParam);
}
}
What code is needed in the message map for Windows messages?
The code calling the function:
SendMessage(GRID_WM_UPDATECELL,(WPARAM)1,(LPARAM)&sDisp);
The function:
LRESULT CNJAGridCtrl::OnUpdateCell(WPARAM wParam, LPARAM lParam)
{
}
The message map line should be
ON_MESSAGE(GRID_WM_UPDATECELL, OnUpdateCell)
and the function signature should be
LRESULT CNJAGridCtrl::OnUpdateCell(WPARAM wParam, LPARAM lParam);
I'm trying to make it so that a user can select text from a read-only edit box, but he won't see the blinking caret. I've been able to make the caret disappear from the edit, but it can still be seen for an instant.
This is my code for the subclass:
LRESULT CALLBACK UserInfoProc (HWND hUserInfoWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
HideCaret(hUserInfoWnd);
return DefSubclassProc(hUserInfoWnd, uMsg, wParam, lParam);
}
It's a modest bit of code, I know, but it almost does what I want.
So what happens is, that when I click the edit, the caret can be seen for an instant (50ms?). I want that it doesn't appear at all. How can I do this? I want the user to still be able to select the text from the edit.
You could try moving the HideCaret() call to after the DefSubclassProc(), since at the moment if a message triggers the caret it won't be until the next message that it's hidden again.
Also, I would guess that the only message that triggers the caret to be shown is WM_SETFOCUS, so you may want to test for that message only. For example,
LRESULT CALLBACK UserInfoProc (HWND hUserInfoWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
LRESULT lRes = DefSubclassProc(hUserInfoWnd, uMsg, wParam, lParam);
if (uMsg == WM_SETFOCUS) // maybe?
HideCaret(hUserInfoWnd);
return lRes;
}
Okay, I have a ListView and I've just worked out how to manually set it's Callback procedure:
// Sets the list view procedure
listproc = (D_ListView *) LocalAlloc(LMEM_FIXED, sizeof(D_ListView));
listproc->oldproc = (WNDPROC)SetWindowLongPtr(g_hList, GWL_WNDPROC, (LONG)&ListViewProc);
SetWindowLongPtr(g_hList, GWL_USERDATA, (LONG)&listproc);
I used a code example I found - D_ListView is just a struct with a WNDPROC variable called oldproc.
Anyhow, I'm sending messages to my ListView to add items. But I don't want to handle the ADD messages manually, I want to pass them onto the ListView's default procedure, and only handle messages that I need to over-ride the functionality for.
LRESULT CALLBACK ListViewProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
// Just a test - we're getting this message so it worked
case LVM_INSERTCOLUMN:
{
cout << "CREATED" << endl;
}
}
WNDPROC* wp;
wp = (WNDPROC*)(::GetWindowLongPtr(hwnd, GWL_WNDPROC));
return ::CallWindowProc(*wp, hwnd, msg, wParam, lParam);
}
In the above, I don't want to deal withe LVM_INSERTCOLUMN: I just want to pass it on.
Any one able to help?
Thanks,
Rob
use getWindowLongPtr (...GWL_USERDATA) to get the pointer to your D_ListView instance and then forward any unwanted messages to oldproc
::CallWindowProc(*listproc->oldproc, hwnd, msg, wParam, lParam);
I have been having trouble with my program trying to gray out ( and disable ) a sub menu item.
What I'm looking for is that the "run" item be disabled unless the required .ini entry is not empty.
My code
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HMENU hmenu = GetMenu(hWnd);
// Reading in ini
if (0 == strcmp(webLocation, "")){
EnableMenuItem(hmenu,ID_WEBSERVICES_RUN,MF_DISABLED | MF_GRAYED);
WritePrivateProfileString(_T("WEBSERVICES"), _T("Location"), _T("Tool Not Found"), WpathStr);
}
I am unsure as to whether I am getting the HMENU correctly and why this code is not working for the desired effect.
Any help with this would be greatly appreciated.
You can't just put this in the WndProc at the top level. WndProc process events, whether the window has been constructed or not. It'll be called many times for many different reasons.
Your WndProc will almost certainly look like a big switch on message. The one you want here is WM_INITDIALOG:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
// jump to a new function that reads the .ini
// and disables the control etc.
return OnInitDialog(hWnd, wParam, lParam);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}