微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我正在尝试测试一个布尔条件,但由于某种原因,它甚至不允许我在我的窗口类中调用函数。我尝试创建一个对象并继承函数,但仍然收到相同的消息。 它会让我做 if(Attach::attachProc) 当它在演示中返回 false 时,它​​总是返回 true。 但不是if(AttachProc())。 窗口类的源代码 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,NULL,NULL);
   //if creation fails return false
   if (!m_hwnd)
       return false;
   b_hwnd = CreateWindow("Button","Inject",WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,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,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()
{
}

窗口.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;
    
};

附加.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);

解决方法

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

一种常见的方法是使用SetWindowLongPtr在额外的窗口内存中存储指向C++对象的指针。然后您可以安全地提取并在 WndProc 函数中使用它。

如何:

  1. 首先为窗口预留一些额外的内存:

     wc.cbWndExtra = sizeof(LONG_PTR);
    
  2. lpParamCreateWindowCreateWindowEx 参数中传递指向对象的指针

    m_hwnd = ::CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,"MyWindowClass","T3chSpl10ts",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,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,(LONG_PTR) cs->lpCreateParams);
             break;
         case WM_COMMAND:
             switch (LOWORD(wparam))
             {
             case ID_INJECT:
                 if (window->attachProc())
                 ...
    

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。