webForumDet fria alternativet

hook problem

7 svar · 342 visningar · startad av Reza

RezaMedlem sedan feb. 2001107 inlägg
#1

Hej

Jag vill kunna ändra mus riktningen så att markören flyttar sig till vänster när jag flyttar musen till höger och vise versa.
Till att börja med har jag registrerat en GetMessage hook i en dll. I hook procken gör jag sedan en enkel beräkning för att flytta markören i motsatt riktning.
I den första versionen hanterade jag bara WM_MOUSEMOVE och WM_NCMOUSEMOVE, detta fungerade bra tills markören skulle flyttas till en dialog (ibland också vanliga fönster), då blev det något fel i beräkningen så att markören aldrig kunde flyttas över dialogen.
Nu har jag testat med att ta bort kontrollen av messge typen (alltså ingen if ( message == WM_**)). Flytt beräkningen utför jag endast om markörens gamla position skiljer sig från dess nya position. Nu fungerar det att flytta den över dialoger och andra fönster, men markör rörelsen är konstig (den hoppar). Ironisk nog blir markör rörelsen nu helt normalt när den flyttas över en dialog????
Vad gör jag för fel????
Här är dll koden:

#include <windows.h>
#include "JasosDll.h"
#include <string>
using namespace std;

HINSTANCE	hInstance;
HWND		hwndProcess;		
POINT		mPos;
POINT		pos;
bool		sabon = true;
int		c = 0;

POINT		oldPos, newPos;

int WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, PVOID pvReserved)
{
	hInstance = hInst;
	return TRUE;
}

EXPORT void CALLBACK start()
{
	SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hInstance, 0);
	hwndProcess = GetActiveWindow();
	GetCursorPos(&oldPos);
}

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
		GetCursorPos(&newPos);
		if(newPos.x > oldPos.x && newPos.x != 0){
			//newPos.x = __max(0, __min(1023, oldPos.x - (newPos.x - oldPos.x)));
			newPos.x = (oldPos.x - (newPos.x - oldPos.x));
			if(!(newPos.x < 0) && !(newPos.x > 1023)){
				oldPos.x = newPos.x;
				SetCursorPos(newPos.x, newPos.y);
			}	
		}

		else if(newPos.x < oldPos.x || newPos.x == 0){
			if(newPos.x == 0){
				newPos.x = 7;
			}
			else{
				newPos.x = (oldPos.x + (oldPos.x - newPos.x));	
			}
			if(!(newPos.x < 0) && !(newPos.x > 1023)){
				oldPos.x = newPos.x;

				SetCursorPos(newPos.x, newPos.y);
			
			}
		}

	return CallNextHookEx(NULL, nCode, wParam, lParam);
}
nikoMedlem sedan juni 20022 599 inlägg
#2

Nu har jag inte kollat koden så det är möjligt att jag svarar uppåt väggarna, men ..

Du är medveten om att dina globala variabler i dll:en är "globala" per process (om det inte är en 16-bitarsdll), vilket innebär att tex oldPos kan byta värde lite slumpmässigt beroende på i vilken process hooken råkar vara mappad när muspekaren rör sig?

Det är inte så att vissa av dina "globala" variabler borde ligga i ett delat minnesutrymme?

RezaMedlem sedan feb. 2001107 inlägg
#3

Hej niko

Det här har jag också funderat på, det kan nog mycket väl vara så. Men samtidigt står det i dokumentationen att globala variabler i globala dll:er ska delas mellan trådar?
Dessutom uppstår problemet även om markören flyttar sig på en dialog ruta ägd av fönstret som pekaren befinner sig på.
Alltså flytten sker fint på huvudfönstret men blir fel när huvudfönstret öppnar upp en dialog och pekaren ska flyttas på denna.
Jag ville bara utesluta allt annat innan jag ger mig in på att testa delad variabel, dessutom vet jag inte riktigt hur jag ska dela variabeln.
Det skulle vara snällt om du kunde köra koden och testa lite.
Tack

RezaMedlem sedan feb. 2001107 inlägg
#4

Jag måste också nämna att det fungerar helt annorlunda nu när jag inte längre har if sats kontrollen på meddelanden.
Som jag nämnde tidigare går det nu att flytta den över dialogen men markören rör sig ”hackigt” när den inte är på en dialog.

nikoMedlem sedan juni 20022 599 inlägg
#5

Reza skrev:

Men samtidigt står det i dokumentationen att globala variabler i globala dll:er ska delas mellan trådar?

Trådar inom en process, ja. Men du gör ju en global hook? Vad som då händer är att GetMsgProc anropas i kontexten av den process som råkar exekevera i processorn just då och värdena på dina "globala" variabler blir unika för den processen. Så som sagt: Om det är så att din logik bygger på att vissa värden är kända i hela systemet (jag har inte läst koden) så måste du dela dem mellan processerna.

//I MSVC:
#pragma data_seg("Shared")
char dinSträng[]="                              ";
long dinLong=0;
//delade variabler måste vara initialiserade, tror jag.
#pragma data_seg()
#pragma comment(linker,"/section:Shared,rws")

Reza skrev:

Jag ville bara utesluta allt annat innan jag ger mig in på att testa delad variabel

Jo, men jag tycker ändå du bör prova eftersom kontextswitcharna kommer fort och det kanske kan förklara "ryckigheten". (Jag gissar ..)

RezaMedlem sedan feb. 2001107 inlägg
#6

Tack, jag ska testa detta och återkommer så fort jag har gjort det!

nikoMedlem sedan juni 20022 599 inlägg
#7

Gör det. Sen undrar jag lite om ditt "manuella" flyttande med SetCursorPos verkligen är "the way to go". Hur häver/kompenserar du egentligen systemets egen förflyttning av muspekaren? Att du sätter en hook innebär väl inte att Windows avstår från att själv behandla meddelandena?

En annan metod kanske kunde vara att använda WH_JOURNALRECORD + WH_JOURNALPLAYBACK och bara modifiera/spegelvända förflyttningarna? Fast nu spekulerar jag eftersom jag inte har en aning om hur man gör det.

RezaMedlem sedan feb. 2001107 inlägg
#8

Återigen tack niko (niko har nu hjälpt mig ca:101 gånger)!
Provade med delat utrymme för variablerna som löste en stor del av problemet, men det fanns också en del timing problem som tog ett tag att upptäcka.
Men nu fungerar det som det ska. WH_JOURNALRECORD och WH_JOURNALPLAYBACK kan kanske inte är rätt alternativ.

Unlike most other global hook procedures, the JournalRecordProc and JournalPlaybackProc hook procedures are always called in the context of the thread that set the hook.

134 ms totalt · 3 externa anrop · v20260731065814-full.2b84b982
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
131 ms — hämta tråd, inlägg och bilagor (db)