Windows API SendMessage + WM_SETTEXT 导致崩溃

发布于 2024-12-03 21:47:07 字数 5157 浏览 0 评论 0原文

我在使用 SendMessageA(handle,WM_SETTEXT,0,(LPARAM)text); 时遇到问题如果在构造函数之外的其他地方使用它会导致崩溃。

MWC.h

#include <Windows.h>
#include <iostream>
#include <string>

class MWC{
private:
    MSG msg;
public:
    MWC();
    ~MWC();
    int mLoop();
    int mClose(UINT);
    class System{
    public:
        System(){ }
        ~System(){ }
        class Form{
        public:
            HWND handle; // Need to access it in order to create other controls
            Form(char*,int,int,int,int);
            Form(char*,int,int);
            ~Form(){ }
            bool Show();
            HWND ReturnHandle();
        };
        class TextBox{
        protected:
            HWND handle;
        private:
            int ID;
        public:
            TextBox(char* text,int width,int height,int x,int y,int id,Form* p);
            TextBox(int width,int height,int x,int y,int id,Form* p);
            ~TextBox(){ }
            bool IsChanged(UINT,WPARAM);
            bool Text(char *);
            int GetId(){ return ID; }
        };

        class messageBox{
        public:
            messageBox(){ };
            ~messageBox(){ };
            bool Show(LPCWSTR,LPCWSTR,UINT);
            bool ShowA(char*,char*,UINT);
            bool ShowA(std::string,std::string,UINT);
        };
    };
};

MWC.cpp

#include "MWC.h"

MWC::MWC(){ }
MWC::~MWC(){ }
int MWC::mLoop(){
    while(GetMessage(&msg,NULL,0,0)) { 
        TranslateMessage(&msg); 
        DispatchMessage(&msg);
    }
    return 1;
}
int MWC::mClose(UINT _msg){
    if(_msg == WM_CLOSE){PostQuitMessage(0);return 1;}
    return 0;
}
MWC::System::Form::Form(char* Title,int width,int height,int x,int y){
    handle =  CreateWindowEx(0,WC_DIALOG,Title,WS_OVERLAPPEDWINDOW | WS_VISIBLE,x,y,width,height,NULL,NULL,NULL,NULL);
}
MWC::System::Form::Form(char* Title,int width,int height){
    handle =  CreateWindowEx(0,WC_DIALOG,Title,WS_OVERLAPPEDWINDOW | WS_VISIBLE,400,100,width,height,NULL,NULL,NULL,NULL);
}

bool MWC::System::Form::Show(){
    return false;
}

HWND MWC::System::Form::ReturnHandle(){
    return handle;
}

MWC::System::TextBox::TextBox(char* text,int width,int height,int x,int y,int id,Form* p){
    ID = id;
    handle = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",text,WS_VISIBLE | WS_CHILD,x,y,width,height,p->handle,(HMENU)id,NULL,NULL);
}
MWC::System::TextBox::TextBox(int width,int height,int x,int y,int id,Form* p){
    ID = id;
    handle = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",WS_VISIBLE | WS_CHILD,x,y,width,height,p->handle,(HMENU)id,NULL,NULL);
    SendMessageA(handle,WM_SETTEXT,0,(LPARAM)"It works here!");
}
bool MWC::System::TextBox::IsChanged(UINT message, WPARAM wParam){
    if(message==WM_COMMAND && HIWORD(wParam)==EN_CHANGE && LOWORD(wParam)==ID){
        return true;
    }
    return false;
}

bool MWC::System::TextBox::Text(char* text){
    if(handle == NULL){
        return 0;
    }
    else{
        //SendMessageA(handle,WM_SETTEXT,0,(LPARAM)text); // It doesn't work here!
        return 1;
    }
    return 1;
}


bool MWC::System::messageBox::Show(LPCWSTR text,LPCWSTR caption,UINT id){
    ::MessageBoxW(NULL,text,caption,id);
    return true;
}

bool MWC::System::messageBox::ShowA(char* text,char* caption,UINT id){
    ::MessageBoxA(NULL,(LPCSTR)text,(LPCSTR)caption,id);
    return true;
}

bool MWC::System::messageBox::ShowA(std::string text,std::string caption,UINT id){
    ::MessageBoxA(NULL,(LPCSTR)text.c_str(),(LPCSTR)caption.c_str(),id);
    return true;
}

Main.cpp

#include "MWC.h"

MWC mwc = MWC();
MWC::System::messageBox mbox = MWC::System::messageBox();
MWC::System::Form form1 = MWC::System::Form("Window",600,600);
MWC::System::TextBox textbox1 = MWC::System::TextBox(600,500,0,0,156,&form1);

BOOL WINAPI myProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
    mwc.mClose(message);    

    //check if text in textbox has been changed by user
    textbox1.Text("Test");
    if(textbox1.IsChanged(message,wParam) == true){

    }
    return false; 
}





int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    SetWindowLong(form1.ReturnHandle(), DWL_DLGPROC, (long)myProc); // to be added in the class
    mwc.mLoop();
    return 0;   
}

问题是.. sendmessage 在(MWC.cpp)上工作得很好:

MWC::System::TextBox::TextBox(int width,int height,int x,int y,int id,Form* p){
    ID = id;
    handle = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",WS_VISIBLE | WS_CHILD,x,y,width,height,p->handle,(HMENU)id,NULL,NULL);
    SendMessageA(handle,WM_SETTEXT,0,(LPARAM)"It works here!"); // TESTING
}

但是如果在这里使用它会导致崩溃:

bool MWC::System::TextBox::Text(char* text){
    if(handle == NULL){
        return 0;
    }
    else{
        //SendMessageA(handle,WM_SETTEXT,0,(LPARAM)text); // It doesn't work here!
        return 1;
    }
    return 0;
}

顺便说一句,我只是一个业余爱好者,正在摆弄 winapi :) 。请随意评论您发现的任何错误!

I'm having trouble with SendMessageA(handle,WM_SETTEXT,0,(LPARAM)text); It results to a crash if used anywhere else except the constructor.

MWC.h

#include <Windows.h>
#include <iostream>
#include <string>

class MWC{
private:
    MSG msg;
public:
    MWC();
    ~MWC();
    int mLoop();
    int mClose(UINT);
    class System{
    public:
        System(){ }
        ~System(){ }
        class Form{
        public:
            HWND handle; // Need to access it in order to create other controls
            Form(char*,int,int,int,int);
            Form(char*,int,int);
            ~Form(){ }
            bool Show();
            HWND ReturnHandle();
        };
        class TextBox{
        protected:
            HWND handle;
        private:
            int ID;
        public:
            TextBox(char* text,int width,int height,int x,int y,int id,Form* p);
            TextBox(int width,int height,int x,int y,int id,Form* p);
            ~TextBox(){ }
            bool IsChanged(UINT,WPARAM);
            bool Text(char *);
            int GetId(){ return ID; }
        };

        class messageBox{
        public:
            messageBox(){ };
            ~messageBox(){ };
            bool Show(LPCWSTR,LPCWSTR,UINT);
            bool ShowA(char*,char*,UINT);
            bool ShowA(std::string,std::string,UINT);
        };
    };
};

MWC.cpp

#include "MWC.h"

MWC::MWC(){ }
MWC::~MWC(){ }
int MWC::mLoop(){
    while(GetMessage(&msg,NULL,0,0)) { 
        TranslateMessage(&msg); 
        DispatchMessage(&msg);
    }
    return 1;
}
int MWC::mClose(UINT _msg){
    if(_msg == WM_CLOSE){PostQuitMessage(0);return 1;}
    return 0;
}
MWC::System::Form::Form(char* Title,int width,int height,int x,int y){
    handle =  CreateWindowEx(0,WC_DIALOG,Title,WS_OVERLAPPEDWINDOW | WS_VISIBLE,x,y,width,height,NULL,NULL,NULL,NULL);
}
MWC::System::Form::Form(char* Title,int width,int height){
    handle =  CreateWindowEx(0,WC_DIALOG,Title,WS_OVERLAPPEDWINDOW | WS_VISIBLE,400,100,width,height,NULL,NULL,NULL,NULL);
}

bool MWC::System::Form::Show(){
    return false;
}

HWND MWC::System::Form::ReturnHandle(){
    return handle;
}

MWC::System::TextBox::TextBox(char* text,int width,int height,int x,int y,int id,Form* p){
    ID = id;
    handle = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT",text,WS_VISIBLE | WS_CHILD,x,y,width,height,p->handle,(HMENU)id,NULL,NULL);
}
MWC::System::TextBox::TextBox(int width,int height,int x,int y,int id,Form* p){
    ID = id;
    handle = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",WS_VISIBLE | WS_CHILD,x,y,width,height,p->handle,(HMENU)id,NULL,NULL);
    SendMessageA(handle,WM_SETTEXT,0,(LPARAM)"It works here!");
}
bool MWC::System::TextBox::IsChanged(UINT message, WPARAM wParam){
    if(message==WM_COMMAND && HIWORD(wParam)==EN_CHANGE && LOWORD(wParam)==ID){
        return true;
    }
    return false;
}

bool MWC::System::TextBox::Text(char* text){
    if(handle == NULL){
        return 0;
    }
    else{
        //SendMessageA(handle,WM_SETTEXT,0,(LPARAM)text); // It doesn't work here!
        return 1;
    }
    return 1;
}


bool MWC::System::messageBox::Show(LPCWSTR text,LPCWSTR caption,UINT id){
    ::MessageBoxW(NULL,text,caption,id);
    return true;
}

bool MWC::System::messageBox::ShowA(char* text,char* caption,UINT id){
    ::MessageBoxA(NULL,(LPCSTR)text,(LPCSTR)caption,id);
    return true;
}

bool MWC::System::messageBox::ShowA(std::string text,std::string caption,UINT id){
    ::MessageBoxA(NULL,(LPCSTR)text.c_str(),(LPCSTR)caption.c_str(),id);
    return true;
}

Main.cpp

#include "MWC.h"

MWC mwc = MWC();
MWC::System::messageBox mbox = MWC::System::messageBox();
MWC::System::Form form1 = MWC::System::Form("Window",600,600);
MWC::System::TextBox textbox1 = MWC::System::TextBox(600,500,0,0,156,&form1);

BOOL WINAPI myProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
    mwc.mClose(message);    

    //check if text in textbox has been changed by user
    textbox1.Text("Test");
    if(textbox1.IsChanged(message,wParam) == true){

    }
    return false; 
}





int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    SetWindowLong(form1.ReturnHandle(), DWL_DLGPROC, (long)myProc); // to be added in the class
    mwc.mLoop();
    return 0;   
}

The thing is .. sendmessage works fine at (MWC.cpp):

MWC::System::TextBox::TextBox(int width,int height,int x,int y,int id,Form* p){
    ID = id;
    handle = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",WS_VISIBLE | WS_CHILD,x,y,width,height,p->handle,(HMENU)id,NULL,NULL);
    SendMessageA(handle,WM_SETTEXT,0,(LPARAM)"It works here!"); // TESTING
}

But it results to a crash if used here:

bool MWC::System::TextBox::Text(char* text){
    if(handle == NULL){
        return 0;
    }
    else{
        //SendMessageA(handle,WM_SETTEXT,0,(LPARAM)text); // It doesn't work here!
        return 1;
    }
    return 0;
}

BTW I'm just an amateur whos messing around with winapi :). Feel free to comment on any bugs you happen to find!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听不够的曲调 2024-12-10 21:47:07

你的对话程序看起来完全错误。您试图在每次对话过程运行时发送 WM_SETTEXT!这可能会导致无限递归以及各种其他问题。

您的 SendMessage 调用绝对没问题,只是无法每次运行对话框过程时都调用它。

我不明白 IsChanged() 函数的含义。你的框架的设计很奇怪。我建议您首先查看一些其他框架(例如 ATL),以获得有关如何围绕 Win32 编写框架的一些想法。或者,更好的是,只使用现有的框架。

Your dialog procedure looks all wrong. You are attempting to send WM_SETTEXT every single time the dialog procedure runs! That probably sets up an infinite recursion and probably all sorts of other issues.

Your SendMessage call is absolutely fine, you just can't make it every time the dialog procedure runs.

I don't understand what the IsChanged() function is all about. The design of your framework is very odd. I suggest you look at some other frameworks (e.g. ATL) first to get some ideas on how to write a framework around Win32. Or, even better, just use an existing framework.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文