DLL and drawing function disappearing - c++

main.cpp (dll) http://pastebin.com/Z811YSz7
Funkcje.h http://pastebin.com/siZrUBh0
When i injected this dll to a game then i dont see letters.
When i maked drawing function in a while(1) then the letters are appearing and disappearing.
How to make the drawing function to be on the top of this game all the time.
#include <windows.h>
#include <vector>
#include "Funkcje.h"
#include <cstdio>
#include <string>
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwreason,
LPVOID lpReversed)
{
switch (fdwreason)
{
case DLL_PROCESS_ATTACH:
PAINTSTRUCT ps;
HDC hdc;
for (size_t i = 0; i < getToplevelWindows().size(); i++){
hdc = GetDC(getToplevelWindows()[i]);
TextOut(hdc, 150, 150, L"TEST", 4);
ReleaseDC(getToplevelWindows()[i], hdc);
}
break;
}
return TRUE;
}

DllMain is only called once, when the DLL is loaded. This is not where you should be putting your code.
In order to properly "inject" code into a process (via DLL or any other mean) you must first determine what function or event in that process you want to hook.
In this case, I suppose you want to hook the window event WM_PAINT, a callback from the system sent to the window's procedure telling it that it should repaint its content for whatever reason. (This may not be always correct though, because a program can use other methods of updating a window content.)
So what you are going to do is find the window handle you want to hook, and replace its callback procedure with your own:
WNDPROC originalProc = SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)myHookProc);
But of course, not before having myHookProc defined and doing its job of hooking WM_PAINT:
LRESULT CALLBACK myHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT originalResult = originalProc(hWnd, uMsg, wParam, lParam); // call original first
if (uMsg == WM_PAINT)
{
PAINTSTRUCT ps;
HDC hdc = GetDC(hWnd);
TextOut(hdc, 150, 150, L"TEST", 4);
ReleaseDC(hWnd, hdc);
}
return originalResult;
}
If you are dealing with multiple windows, you may want to use a std::unordered_map<HWND, WNDPROC> to keep relation between each window handle and its original procedure.

Related

unexpected behaviour in multiline edit in winapi

I am creating a program of painting a text in multiline edit using windows api in c++. It consists of WM_PAINT message which paints the text in client area, but the caret shows unexpected behaviour in edit. It sometimes does not print characters, sometimes printed characters hides.
The code is
#define UNICODE
/*
**
**ALL HEADER FILES
**
*/
#include<wchar.h>
#include<windows.h>
#include <errno.h>
#include<conio.h>
#include<iostream>
#include<stdio.h>
#include<resource.h>
/*
**
**ALL DEFINES CONSTANT
**
*/
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0A00
LRESULT CALLBACK WindowProcedure(HWND,UINT,WPARAM,LPARAM);
using namespace std;
HWND hwnd_handle;
HWND hw;
HINSTANCE his;
int WINAPI WinMain(HINSTANCE hvalue,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
his=hvalue;
/////com=nCmdShow;
LPWSTR myname=L"MY WINDOWS CLASS";
MSG msg={0};
WNDCLASSW wc;
wc.hbrBackground=(HBRUSH)COLOR_BTNFACE;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.lpszMenuName=NULL;
wc.lpszClassName=myname;
wc.hCursor=NULL;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.style=0;
wc.hInstance=hvalue;
wc.lpfnWndProc=WindowProcedure;
if(!RegisterClassW(&wc))
{
return 0;
}
///////main window
hwnd_handle=CreateWindowW(myname,L"CODE EDITOR",WS_OVERLAPPEDWINDOW,240,80,600,600,NULL, NULL,hvalue, NULL);
ShowWindow(hwnd_handle,nCmdShow);
UpdateWindow(hwnd_handle);
////////HWND hwnd=CreateWindowW(L"STATIC",L"CODE EDITOR",WS_OVERLAPPEDWINDOW,24,8,60,6,hwnd_handle, NULL,hInstance, NULL);
while(GetMessageW(&msg,NULL,NULL,NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
/////main_structure(hwnd);
hw=CreateWindowW(TEXT("edit"),TEXT(""), WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE|ES_AUTOHSCROLL|ES_AUTOVSCROLL ,3,0,600,600,hwnd,NULL,his,NULL);
}
break;
case WM_COMMAND:
{
/////menu_function(hwnd,wParam);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT info;
HBRUSH hbrush;
HDC hdc = BeginPaint(hw,&ps);
wcout<<"vishal";
TextOut(hdc,20,20,L"vishak",6);
EndPaint(hw,&ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
}
///////all men
Since you are using an edit control as the client area of your window don't handle WM_PAINT yourself; instead add the text to the edit control (using SendMessage with EM_SETTEXT or possibly EM_REPLACESEL) and let it do the drawing.
Also, you should handle WM_SIZE and set the edit control to the actual client area size.

I want to make a clock(GUI program) via windows api, but the text on the clock doesn't change?

I want the text change as time changes like a clock, however, it doesn't change. I found that the text will change when I minimize or maximize the window.
I guess I should redraw the window, but I am new to windows api, anyone good advice?
This is the main.cpp codeļ¼š
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
//....
}
void Paint(HWND hwnd, LPCTSTR txt)
{
UpdateWindow(hwnd);
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(hdc, txt, -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
}
// Thread function
DWORD WINAPI ThreadFun(LPVOID lpParameter)
{
HWND hwnd = (HWND)lpParameter;
while (1)
{
string dateStr = Ticker::GetCurrentTimeStr();
Paint(hwnd, dateStr.c_str());
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
CreateThread(NULL, 0, ThreadFun, hwnd, 0, NULL);
}
return 0;
case WM_PAINT:
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
You need to call InvalidateRect to tell the system the drawing area has changed.
Edit
Instead of creating a new thread, you can create a timer with SetTimer (see example) and respond to WM_TIMER message. Call InvalidateRect in response to WM_TIMER, to repaint the window every second.
Do all of the painting in response to WM_PAINT.
Use BeginPaint/EndPaint only in response to WM_PAINT, don't use BeginPaint/EndPaint elsewhere.

Changing HWND Window Procedure in runtime

I'm working in an IDE which creates a hwnd and its respective WndProc LRESULT CALLBACK. I need to change the WndProc to a custom one.
I've read that SetWindowLong would do the job, but I can't find any working example. For example:
HWND hwnd; //My window
SetWindowLong(hwnd, GWL_WNDPROC, myNewWndProc);
The third parameter for SetWindowLong is a Long as the name of the function names it. How can I make a reference from my WndProc function to a Long?
My WndProc:
LRESULT CALLBACK WndProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
msg_dev(toString(uMsg));
switch(uMsg){
case WM_MOUSEMOVE:
SetCursor(LoadCursor(NULL, IDC_HAND));
break;
case WM_LBUTTONDOWN:
msg_dev("Button down!");
break;
default:
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
};
You need to use something like this:
WNDPROC prevWndProc;
...
prevWndProc = (WNDPROC) SetWindowLongPtr(hwnd, GWL_WNDPROC, (LONG_PTR)&myNewWndProc);
...
LRESULT CALLBACK myNewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
msg_dev(toString(uMsg));
switch(uMsg)
{
case WM_MOUSEMOVE:
SetCursor(LoadCursor(NULL, IDC_HAND));
break;
case WM_LBUTTONDOWN:
msg_dev("Button down!");
break;
}
return CallWindowProc(prevWndProc, hwnd, uMsg, wParam, lParam);
}
See 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
That being said, you should use SetWindowSubclass() instead of SetWindowLongPtr(). Let it handle this for you. See this article for more details:
Safer subclassing
For example:
#define MY_SUBCLASS_ID 1
SetWindowSubclass(hwnd, &mySubClassProc, MY_SUBCLASS_ID, 0);
...
LRESULT CALLBACK mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
msg_dev(toString(uMsg));
switch(uMsg)
{
case WM_MOUSEMOVE:
SetCursor(LoadCursor(NULL, IDC_HAND));
break;
case WM_LBUTTONDOWN:
msg_dev("Button down!");
break;
case WM_NCDESTROY:
RemoveWindowSubclass(hWnd, &mySubClassProc, uIdSubclass);
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
A simple cast does the job.
SetWindowLongPtr(hwnd, GWL_WNDPROC, (LONG_PTR)&myNewWndProc);
Otherwise It would be incompatible types: LRESULT and LONG.
The MSDN documentation for SetWindowLong() states that GWL_WNDPROC
Sets a new address for the window procedure.
This means that your third parameter should be a pointer to a function. Your SetWindowLong() call should therefore look like this:
SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR)&myNewWndProc);
Note also the Remarks section that states:
An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc.
You can use setWindowLong to address your problem.
setWindowLong(hwnd,GWL_WNDPROC,(LONG)newWindowProcedure);
However you would be setting the window procedure twice. Once with the IDE default and then to yours. What you need to dobis set the window procedure when the window is being REGISTERED.
#include <windows.h>
void registerWindow();
void createWindow();
void messageLoop();
int main()
{
registerWindow();
createWindow();
messageLoop();
}
LRESULT CALLBACK myWindowProcedure(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
return DefWindowProc(hwnd,msg,wparam,lparam);
}
void registerWindow()
{
/** This is the important part.
* Find this part in your code.
* Set WNDCLASS::lpfnWndProc to what ever
* window procedure you want.
**/
WNDCLASS wc = {};
wc.lpfnWndProc = myWindowProcedure;
wc.hInstance = hInstance;
wc.lpszClassName = "CLASS NAME";
RegisterClass(&wc);
// WARNING: Your app will crash at runtime if the
// windows procedure is "NOT PROPER"
}
void createWindow()
{
auto hwnd = CreateWindowEx(
0, // Optional window styles.
"CLASS NAME", // Window class
"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
HINSTANCE(), // Instance handle
NULL // Additional application data
);
ShowWindow(hwnd, nCmdShow
}
void messageLoop()
{
MSG msg;
while( GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
You have to use SetWindowLongPtr (which on 32-bit is a macro but a separate function on 64-bit) to ensure compatibility with both 32- and 64-bit systems.
Syntax would be as follows:
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)&myNewWndProc);
Note SetWindowLongPtr is used instead of SetWindowLong, and GWLP_WNDPROC is used as the nIndex constant.

Drawing a Line Outside of WM_PAINT

Usually, to draw a line we draw it in WM_PAINT
LRESULT CALLBACK Display::DisplayWindowProc(HWND hWnd,UINT msg,WPARAM wParamm,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch(msg)
{
case WM_PAINT:
hdc = BeginPaint(hWnd,&ps);
MoveToEx(hdc,0,0,0);
LineTo(hdc,100,100);
EndPaint(hWnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hWnd, msg, wParamm, lParam);
}
But , i want to draw line whenever i want, simple example:
int WINAPI WinMain
(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR cmdLine,
int showCmd
)
{
//Do Other Things
Display dislpay;
display.DrawLine();
//Do Other Things
}
My Program is Object Oriented and i display things in Display class and i was wondering if i can do a draw line in a function like DrawLine() in Display Class.
You can create an off-screen DC, and select an appropriately sized bitmap, and use that to draw whenever you want. Then on WM_PAINT you blit from the off-screen DC into the windows DC.

Loading and painting bmp win32api c++

i am trying to show a bmp in the screen using this code: (this code is from a book but i cant show the windows when i compile only appear the white window)
#include "resource2.h"
#include <vector>
#include <windows.h>
using namespace std;
HWND window1;
HWND window2;
HINSTANCE happ;
HDC handledevice;
PAINTSTRUCT ps;
HBITMAP hbitmap;
BITMAP bitmap;
HDC bmhdc;
HBITMAP oldbm;
LRESULT CALLBACK WindTyp1(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch (msg)
{
case WM_KEYDOWN:
if (wparam==VK_ESCAPE)
{
DestroyWindow(window1);
}
return 0;
case WM_PAINT:
handledevice=BeginPaint(hwnd,&ps);
BitBlt(handledevice,0,0,bitmap.bmWidth,bitmap.bmHeight,bmhdc,0,0,SRCCOPY);
EndPaint(hwnd,&ps);
return 0;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}
LRESULT CALLBACK WindTyp2(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch (msg)
{
case WM_KEYDOWN:
if (wparam==VK_F1)
{
DestroyWindow(window1);
}
if (wparam==VK_F2)
{
DestroyWindow(window2);
}
if (wparam==VK_ESCAPE)
{
DestroyWindow(window1);
DestroyWindow(window2);
}
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}
int WINAPI WinMain(HINSTANCE histance,HINSTANCE hprevinstance,PSTR cmdline,int showcmd)
{
happ=histance;
MSG msg;
hbitmap=LoadBitmap(happ,MAKEINTRESOURCE(happ,IDB_BITMAP1));
GetObject(hbitmap,sizeof(BITMAP),&bitmap);
bmhdc=CreateCompatibleDC(handledevice);
SelectObject(bmhdc,&bitmap);
//clase 1
WNDCLASS windowstyle1,windowstyle2;
windowstyle1.cbClsExtra=0;
windowstyle1.cbWndExtra=0;
windowstyle1.hbrBackground=(HBRUSH) ::GetStockObject(WHITE_BRUSH);
windowstyle1.hCursor=::LoadCursor(0,IDC_ARROW);
windowstyle1.hIcon=::LoadIcon(0,IDI_APPLICATION);
windowstyle1.hInstance=histance;
windowstyle1.lpfnWndProc=WindTyp1;
windowstyle1.lpszClassName="Class 1";
windowstyle1.lpszMenuName=0;
windowstyle1.style= CS_HREDRAW | CS_VREDRAW;
//clase 2
windowstyle2.cbClsExtra=0;
windowstyle2.cbWndExtra=0;
windowstyle2.hbrBackground=(HBRUSH) ::GetStockObject(BLACK_BRUSH);
windowstyle2.hCursor=::LoadCursor(0,IDC_ARROW);
windowstyle2.hIcon=::LoadIcon(0,IDI_APPLICATION);
windowstyle2.hInstance=histance;
windowstyle2.lpfnWndProc=WindTyp2;
windowstyle2.lpszClassName="Class 2";
windowstyle2.lpszMenuName=0;
windowstyle2.style= CS_HREDRAW | CS_VREDRAW;
//registrar ambas clases
RegisterClass(&windowstyle1);
RegisterClass(&windowstyle2);
//crear ventanas
window1=::CreateWindow("Class 1","Ventana Blanca",WS_OVERLAPPEDWINDOW,0,0,1400,1000,0,0,happ,0);
if (window1==0)
::MessageBox(0,"error failed to create window","error",0);
//Show & Update
ShowWindow(window1,true);
UpdateWindow(window1);
//Message Loop
ZeroMemory(&msg,sizeof(MSG));
while (GetMessage(&msg,0,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Have a look at this example here
http://www.functionx.com/win32/Lesson13.htm
bmhdc=CreateCompatibleDC(handledevice);
IN WinMain you're using handledevice - which isn't yet initialised, so selecting the bitmap would cause problems, but it's probably 0, so it would use the desktop DC. Usually I wouldn't do this in WinMain but in paint like in the example in the url.
hth
You are making life harder for yourself than necessary. The way you are expected to do this is with a STATIC window with the SS_BITMAP style.
I realise this is not an indirect answer to your question but I offer it since it will make your task much simpler - let the system do the heavy lifting for you!