Click here to Skip to main content
15,888,816 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello All,
I am trying to monitor a third party application that is not supported anymore.
I currently have a process in a timer thats been set as SetTimer(1,1,NULL) that monitors a pixel as to when it changes color. Using the timer I have been able to capture 95 - 97% of the changes.
This is what I am using in the timer function:
static int Count=0;
CString Test;
HWND Monitoring_App = FindWindow(ClassName,NULL);
HDC hDC = GetDC(Monitoring_App);
COLORREF Color2Test = GetPixel(hDC,x,y);
ReleaseDC(Monitoring_App,hDC);
DeleteDC(hDC);
if(Color2Test == RGB(r,g,b))
{
Count++;
Test.Format("%d", Count);
m_CountText.SetWindowText(Test);
}
SetTimer(1,1,NULL);

Is there a better way to do this?
I could be wrong, will it be possible for me to capture the remainng 5 - 3 %, if I use a thread to monitor the change instead of the timer?
I have no clue about threads.
Once again any suggetions good or bad (there is never bad, we get to learn from them) will be greatly appreciated.
Posted
Comments
Sergey Alexandrovich Kryukov 3-Jul-12 15:28pm    
Just a note:
The solution could be a bit worse or a bit better than yours, but it can never be "good". Not just "monitoring" of unsupported application not designed for such monitoring is wrong, just using of unsupported application is wrong. You will never be happy with that until you finally replace it with something supported...
--SA
Code-o-mat 3-Jul-12 15:39pm    
Wouldn't your method fail if your monitored application's window is overlapped by some other window, minimized or hidden some way, like dragged off screen or somesuch?
FISH786 3-Jul-12 18:06pm    
Sergey Alexandrovich Kryukov:
Yes. I am trying to replace it just short of that 3-5%. However it's been a pain. It's just I am learning to programme at the same time.
Code-o-mat:
Yes. It does fail. However I am short of that 3-5% to be able to reverse engineer and replace it.
Stefan_Lang 5-Jul-12 8:07am    
On a sidenote, if you wish to reply to someone's comment, please use the [Reply] link at the top right of that comment. Your comment here is just a comment to your own posting and the only person being notified of it will be you. ;-)

Okay then,

This method that you've employed is known as polling. It is notorious for two reasons -
(a) cpu resources are used even when there's nothing new to report.
(b) when more than 1 target event occurs between polling events, you lose data.

An option that come to mind is that of subclassing the window.

It will require some knowledge of how the program works internally.

Subclassing the window has the consequence that you'll know of the event before it happens, but won't get another notification until just before the next event happens. This will complicate logic somewhat if you want to do anything with the new data, other than just count the times it changes.

I'd look at the program using OllyDbg or IDA Pro if I knew what it was.
 
Share this answer
 
Comments
Espen Harlinn 3-Jul-12 17:10pm    
5'ed! - call the original procedure first, and then after the procedure has performed the painting OP can get the pixel from the DC.
FISH786 3-Jul-12 18:25pm    
enhzflep:
When you mention Subclass : In short It's the same as hooking and monitor the changes.
I am new at this. I have been reading as thats how I am learning programming is hands on.
Well appreciate the feedback.
Sergey Alexandrovich Kryukov 4-Jul-12 0:30am    
Some good points here; my 5.
--SA
Inject a dll into the legacy application, perhaps using CreateRemoteThread[^] or by listing your dll under the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs registry key.

Once you have code running inside the process you can get the original procedure for the window you want to monitor using the GetWindowLongPtr[^] and the replace it with your own procedure using SetWindowLongPtr[^].

You will then be able to handle each WM_PAINT message for the window you want to monitor after you have called the original windows procedure.

Best regards
Espen Harlinn
 
Share this answer
 
Comments
enhzflep 3-Jul-12 17:03pm    
My +5 - I'd forgotten about the requirement to be running in the same process to snag the WNDPROC. On a side note, SetWindowLongPtr will return the old WNDPROC when you replace the WNDPROC - you don't need to get it first.
Espen Harlinn 3-Jul-12 17:05pm    
True - and thanks :-D
FISH786 3-Jul-12 18:15pm    
Espen Harlinn:

I am just learning to programme. If I understood your Solution correct. In short first I would be creating a Hook for WM_PAINT to the thirdparty application and if WM_PAINT gives location of the paint, I should have the full 100% from this process.
If I am right, there will be work cut out for me. :)
Thank you.
Espen Harlinn 4-Jul-12 3:52am    
The code for the handling would be similar to what you've got. In windows programming a hook has a special meaning, what I propose is often called window subclassing - and, yes, you should get a 100% :-D
FISH786 6-Jul-12 20:24pm    
One last question I hope. How do I convert the screen coordinates that I got from WM_PAINT to the client coordinates?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900