【问题标题】:Windows API SendMessage + WM_SETTEXT results to a crashWindows API SendMessage + WM_SETTEXT 结果导致崩溃
【发布时间】:2011-09-12 13:26:22
【问题描述】:

我在使用 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 的业余爱好者 :)。随意评论您碰巧发现的任何错误!

【问题讨论】:

  • 你的'text' null 终止了吗?
  • 您遗漏了重要部分:您如何调用Text 方法?
  • 我不认为终结者很重要,我尝试添加它但它总是崩溃。
  • 我建议您将代码库修剪到重现崩溃所需的绝对最小值,然后在此处发布结果。
  • @Raymond main.cpp 第 13 行:textbox1.Text("Test");

标签: c++ winapi crash sendmessage


【解决方案1】:

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

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

我不明白IsChanged() 函数是什么意思。你的框架设计很奇怪。我建议你先看看其他一些框架(例如 ATL),以了解如何围绕 Win32 编写框架。或者,更好的是,只使用现有的框架。

【讨论】:

  • 天哪,我不小心在 BOOL WINAPI myProc 而不是 WinMain 中添加了函数调用 非常感谢大卫!
猜你喜欢
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-09
  • 1970-01-01
  • 1970-01-01
  • 2018-01-23
相关资源
最近更新 更多