非静态成员引用必须相对于特定对象 C++

A non static member reference must be relative to a specific object c++

我正在尝试测试布尔条件,但出于某种原因,它甚至不允许我调用 window class 中的函数。我已经尝试创建一个对象并继承函数,但仍然收到相同的消息。 它会让我做 if(Attach::attachProc) 当它在演示中意味着 return false 时,它​​总是 returns true。 但不是 if(AttachProc())。 window class 的来源 Windows.cpp

#include "Window.h"
#include "Attach.h"
Window* window = nullptr;
Attach attach;
Window::Window()
{
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    
    switch (msg)
    {
    case WM_CREATE:
    {
        
        //Event fired when the windows will be created
        break;
    }
    case WM_COMMAND:
        switch (LOWORD(wparam))
        {
        case ID_INJECT:
            if (Attach::attachProc())
            {
                MessageBox(0, "injected", "", MB_ICONERROR | MB_OK);
            }
            else
            {
                MessageBox(0, "faile to inject", "", MB_ICONERROR | MB_OK);
            }
        default:
            break;
        }
    case WM_DESTROY:
    {
        window->onDestroy();
        //Event fired when the window will be destroyed
        ::PostQuitMessage(0);
        break;

    }

    default:
        return ::DefWindowProc(hwnd, msg, wparam, lparam);

    }
    return NULL;
}
bool Window::init()
{
    WNDCLASSEX wc;
    wc.cbClsExtra = NULL;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.cbWndExtra = NULL;
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.hInstance = NULL;
    wc.lpszClassName = "MyWindowClass";
    wc.lpszMenuName = "";
    wc.style = NULL;
    wc.lpfnWndProc = WndProc;

    if (!::RegisterClassEx(&wc))
        return false;

    if (!window)
        window = this;

   m_hwnd = ::CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "MyWindowClass", "T3chSpl10ts", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT
        , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
   //if creation fails return false
   if (!m_hwnd)
       return false;
   b_hwnd = CreateWindow("Button", "Inject",
       WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 20, 20, 100, 30,
       m_hwnd, (HMENU)ID_INJECT, GetModuleHandle(NULL), NULL);

   //show up the window
   ::ShowWindow(m_hwnd, SW_SHOW);
   ::UpdateWindow(m_hwnd);


   //set this flag to indicate that the window is initialized and running
   m_is_run = true;
      return true;
}

bool Window::broadcast()
{
    MSG msg;
    while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    Sleep(0);

    return true;
}

bool Window::release()
{
    //Destroy the window
    if (!::DestroyWindow(m_hwnd))
        return false;
    return true;
}

bool Window::isRun()
{
    return m_is_run;
}

void Window::onDestroy()
{
    m_is_run = false;
}

Window::~Window()
{
}

Window.h

    #pragma once
#include <Windows.h>
#include "Attach.h"
#define Button 0
#define ID_INJECT 1
class Window : public Attach
{
public:
    Window();
    ~Window();
    bool init();//Initializes the window
    bool broadcast();

    bool isRun();
    bool release();
    virtual void onDestroy();
    //virtual void onCreate();
    //virtual void onUpdate();
    
protected:
    HWND m_hwnd;
    HWND b_hwnd;
    bool m_is_run;
    
};

attach.h

    #pragma once
#include<Windows.h>
#include<TlHelp32.h>
#include<cstdlib>
#include<iostream>

class Attach
{
public:
    bool attachProc();
    
protected:
    char procName[12]{ "Hi" };
    HANDLE hProc = NULL;
    DWORD pID;
};
template <class datatype>
void wpm(datatype valToWrite, DWORD addressToWrite);
template <class datatype>
datatype rpm(DWORD addressToRead);

您正试图在 window 过程中使用方法。问题是 window 过程是一个自由函数,这意味着它没有 this 对象,只有一个 HWND 句柄。您必须首先确定调用 window 过程的 Window 对象。

一种常见的方法是使用SetWindowLongPtr 在额外的window 内存中存储指向C++ 对象的指针。然后就可以放心的提取出来,用在WndProc函数中了。

如何:

  1. 首先为window:

    保留一些额外的内存
     wc.cbWndExtra = sizeof(LONG_PTR);
    
  2. 传递指向CreateWindowCreateWindowEx

    lpParam参数中对象的指针
    m_hwnd = ::CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "MyWindowClass", "T3chSpl10ts",
         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT
         , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, this);
    //if creation fails return false
    if (!m_hwnd)
        return false;
    
  3. 在以后处理 WM_CREATEWM_NCCREATE 消息时将指针存储在该额外内存中 在 WndProc 中使用它:

     LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
     {
         Window *window = (Window *) GetWindowLongPtr(hwnd, 0);
         CREATESTRUCT* cs;
         ...
         case WM_CREATE:
             cs = (CREATESTRUCT*)lParam;
             ::SetWindowLongPtr(hwnd, 0, (LONG_PTR) cs->lpCreateParams);
             break;
         case WM_COMMAND:
             switch (LOWORD(wparam))
             {
             case ID_INJECT:
                 if (window->attachProc())
                 ...
    

WM_NCCREATEWM_CREATE 是发送到 window 的第一条消息。在那一刻初始化指向对象的指针允许在其他消息中使用它,例如 WM_SIZE...