-4

I want to control other running programs directly by CallWindowProc instead of SendMessage, there is my code:

#define UNICODE
#include <Windows.h>
#include <stdio.h>
int main(){
    HWND hwnd;
    scanf("%d", &hwnd);
    WNDPROC l = (WNDPROC)GetWindowLongPtr(hwnd, GWL_WNDPROC);
    CallWindowProc(l, hwnd, WM_PAINT, NULL, NULL);
    return GetLastError();
}

It is very simple but after I entered the obtained HWND of any other running window by spy++, it failed with return value 5. Which means Permission Denied by GetLastError(). I am confused. So I'll appreciate if someone can help me.

I'm using Visual studio 2010 express(C++) and I open the IDE in administrator mode. I'm also using Windows 7 and I have closed my UAC.

Thanks in advance.

Ðаn
  • 10,934
  • 11
  • 59
  • 95
Lyronx L
  • 13
  • 5
  • 1
    [GetWindowLongPtr](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowlongptrw) returns a pointer (potentially, anyway). A pointer is only meaningful within the process it is associated with. Taking a pointer from one process and attempting to use it in a different process is a meaningless operation. Rather than asking about your proposed solution, why don't you ask about the *real* issue you are trying to solve? It is evident, that your solution isn't a solution. – IInspectable Mar 20 '20 at 16:22

1 Answers1

1

A window has thread affinity. Its window procedure can be directly called only by the same thread that created the window itself. So you can't use CallWindowProc() from another thread, let alone another process.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you. I'll try Sendmessage. Can it do the same thing as CallWindowProc? – Lyronx L Mar 20 '20 at 16:19
  • @lyr: That's an awkward question. Why would there be *two* API calls that can *"do the same thing"*? The mundane answer is: No. But since you withhold the *real* problem you are trying to solve, there's not much we can do to help you arrive at that goal. – IInspectable Mar 20 '20 at 16:31
  • For reference: [Thread affinity of user interface objects, part 1: Window handles](https://devblogs.microsoft.com/oldnewthing/20051010-09/?p=33843). – IInspectable Mar 20 '20 at 16:41
  • 1
    @LyronxL `SendMessage` won't help either. Nothing exists that allows you to send `WM_PAINT` messages directly. Your real problem is that you have asked about your solution rather than your problem. – David Heffernan Mar 20 '20 at 17:07
  • @David Heffernan I'm sorry but, can you please tell me why cannot I use `SendMessage` and let the target HWND draw on my memory HDC? I have tried and yes, I cannot use `SendMessage(hwnd, WM_PAINT, (WPARAM)my_memory_hdc, NULL)` to draw on my own memory HDC, it remains black. I want to write my own `PrintWindow` function and the function can draw not only a window, but also subwindow or child components, even context menu. Thank you in advance. – Lyronx L Mar 22 '20 at 01:24
  • @LyronxL because 1) the wParam of WM_PAINT is not an HDC, and 2) an HDC can only be used in the thread that creates it, you cant use it across thread or process boundaries. There is no way to write your own custom PrintWindow() function without injecting code into the thread that owns the window that you want to draw. What is wrong with just using PrintWindow() itself? – Remy Lebeau Mar 22 '20 at 03:52