VincentWei/MiniGUI

关于托管窗口丢失消息的问题

htk719809837 opened this issue · 13 comments

你好,项目打算将3.0升级成5.0,但是遇到一个问题:
场景一:
模拟一个注册账号流程,有一个主界面A,两个子界面B、C
A窗口用于输入账户名,B窗口用于输入手机号,C窗口用于输入验证码;
A窗口创建在根窗口上,A窗口创建B窗口,B窗口创建C窗口,在创建之后A和B都不关闭;
当用户点击C窗口输入完成验证码以后,C窗口收到注册账号完成的标志,然后然后通过循环依次给自己、B、A发一个Close消息依,经过测试发现,关闭完C窗口自己以后,B和A的close消息虽然发出去了,但是都不处理,像是被丢了,但是3.0不会出现这个情况。

场景二:
模拟一个设置界面:有一个手机桌面界面ROOT、主设置界面A、基础设置界面B、时间设置界面C;
用户需要设置时间,那么要通过ROOT到A再到B再到C才可以进行设置时间。
当前需求是:用户如果在C界面20秒没有操作,那么ROOT界面会对所有的界面进行消息广播,给A、B、C界面广播一个close的消息,让当前所有的界面都关闭,从而做到超时退出到手机桌面,但是实际测试的时候发现,只有C界面被关闭了,回到了基础设置B界面。并没有回到ROOT界面。同样的情况3.0并不出现。 当C被超时广播的消息关闭以后,回到了B界面,再过20秒,B界面会被关闭。相当于本来20秒可以回到ROOT界面的,但是现在要ABC三个界面都超时20秒才可以。

是不是底层丢了消息?

MiniGUI 内部不会主动过滤 CLOSE 消息。

5.0 版本开始,多线程模式下的托管机制发生了一些变化,你可能需要检查这些主窗口的托管关系,也就是创建主窗口时的 hHosting 设置。

如果不能解决,请给出重现问题用的代码。

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include <stdio.h>
#include <string.h>
HWND hMainWnd;
static void pwdlogin_ime_next_deal(HWND hWnd, UINT dwId, WPARAM dwNc, LPARAM add_data)
{
HWND hWndParent = GetParent(hWnd);
HWND hWndHosting =HWND_INVALID;
switch (dwId)
{
case 104:
do
{ printf("close hwnd id is : %x\n",hWndParent);
PostMessage(hWndParent, MSG_CLOSE, 0, 0);
}while((hWndParent = GetHosting(hWndParent))!= hMainWnd);
break;

	case 105:
		printf("105\n\n");
		BroadcastMessage(MSG_CLOSE, 0xFF, 0);
		break;

		}
return ;

}
static LRESULT pwdlogin_ime_next_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
      printf("44444444 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_ime_next_hWnd = CreateWindowEx(CTRL_BUTTON,
        "44444444444",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        104,
        50, 100, 105, 40, hWnd, 0);
        SetNotificationCallback(pwdlogin_ime_next_hWnd, (NOTIFPROC)pwdlogin_ime_next_deal);
        HWND pwdlogin_ime_next_111hWnd = CreateWindowEx(CTRL_BUTTON,
        "5555555",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        105,
        50, 50, 40, 40, hWnd, 0);
        SetNotificationCallback(pwdlogin_ime_next_111hWnd, (NOTIFPROC)pwdlogin_ime_next_deal);
        break;
    }

case MSG_CLOSE:
    DestroyMainWindow (hWnd);
 MainWindowThreadCleanup (hWnd);
 break ;
 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static void pwdlogin_ime_deal(HWND hWnd, UINT dwId, WPARAM dwNc, LPARAM add_data)
{
HWND hWndParent = GetParent(hWnd);
DLGTEMPLATE stDlg;
switch (dwId)
{
case 102:

                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 0;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWndParent, pwdlogin_ime_next_proc, 0);
	     break;
	     

		}
return ;

}
static LRESULT pwdlogin_ime_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
      printf("33333 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_ime_hWnd = CreateWindowEx(CTRL_BUTTON,
        "333333333",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        102,
        50, 100, 105, 40, hWnd, 0);
        SetNotificationCallback(pwdlogin_ime_hWnd, (NOTIFPROC)pwdlogin_ime_deal);
        break;
    }
            case MSG_CLOSE:
    DestroyMainWindow (hWnd);
 MainWindowThreadCleanup (hWnd);
 break ;

 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static void pwdlogin_window_deal(HWND hWnd, UINT dwId, WPARAM dwNc, LPARAM add_data)
{
HWND hWndParent = GetParent(hWnd);
DLGTEMPLATE stDlg;
switch (dwId)
{
case 101:

                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 0;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWndParent, pwdlogin_ime_proc, 0);
	     break;

		}
return ;

}
static LRESULT pwdlogin_window_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
       printf("2222 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_window_hWnd = CreateWindowEx(CTRL_BUTTON,
        "222222",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        101,
        50, 100, 105, 40, hWnd, 0);
        SetNotificationCallback(pwdlogin_window_hWnd, (NOTIFPROC)pwdlogin_window_deal);
        break;
    }
    case MSG_CLOSE:
    DestroyMainWindow (hWnd);
 MainWindowThreadCleanup (hWnd);
 break ;
 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static LRESULT HelloWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message) {
    case MSG_CREATE:
    printf("111111 hwnd id is : %x\n",hWnd);
        hWnd = CreateWindowEx(CTRL_BUTTON,
        "11111111111",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_TRANSPARENT,
        100,
        50, 50, 105, 40, hWnd, 0);
        break;
    case MSG_COMMAND:
    	if(100 == wParam)
    	{	
    
    	    HWND    hWndParent = GetParent(hWnd);
    	    DLGTEMPLATE stDlg;
                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 0;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWnd, pwdlogin_window_proc, 0);
    	}
    	 break;
    case MSG_CLOSE:
     // DestroyMainWindow (hWnd);
      //PostQuitMessage (hWnd);
        break;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);

}

int MiniGUIMain (int argc, const char* argv[])
{
MSG Msg;

MAINWINCREATE CreateInfo;


CreateInfo.dwStyle = WS_VISIBLE | WS_CAPTION;
CreateInfo.dwExStyle = WS_EX_NONE;
CreateInfo.spCaption = "Hello";
CreateInfo.hMenu = 0;
CreateInfo.hCursor = GetSystemCursor(0);
CreateInfo.hIcon = 0;
CreateInfo.MainWindowProc = HelloWinProc;
CreateInfo.lx = 0;
CreateInfo.ty = 0;
CreateInfo.rx = 480;
CreateInfo.by = 272;
CreateInfo.iBkColor = COLOR_lightwhite;
CreateInfo.dwAddData = 0;
CreateInfo.hHosting = HWND_DESKTOP;
hMainWnd = CreateMainWindow (&CreateInfo);
printf("    HWND hMainWnd id is : %x \n",hMainWnd);
if (hMainWnd == HWND_INVALID)
    return -1;
ShowWindow(hMainWnd, SW_SHOWNORMAL);

while (GetMessage(&Msg, hMainWnd)) {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
}
MainWindowThreadCleanup (hMainWnd);
return 0;

}
#ifdef _MGRM_THREADS
#include <minigui/dti.c>
#endif

这个是运行在线程模式下的
启动以后分别点击按钮,知道出现最后一个界面,然后点击44444内容按钮,按理来说应该关闭所有的窗口,只保留主窗口,虽然发送了关闭的消息给对应的窗口,但是只关闭了当前窗口。
111111 hwnd id is : 91a524c0
HWND hMainWnd id is : 91a524c0
2222 hwnd id is : 91a530f0
33333 hwnd id is : 91a53590
44444444 hwnd id is : 91a539b0
close hwnd id is : 91a539b0
close hwnd id is : 91a53590
close hwnd id is : 91a530f0

如果点击555的按钮,广播给所有的窗口(除了根窗口)一条关闭消息,但是也只是关闭了当前窗口,不会关闭其他窗口

We have fixed this bug. It caused by a bug in the implementation of ThrowAwayMessages() function: The messages in the message queue were thrown away because a bad test condition, while the implementation of version 3.0.x is good.

Please fetch the latest code from rel-5-0 branch.

Thanks a lot!

你好,目前已知一个崩溃缺陷,这个缺陷非常紧急,如果有时间允许我会提供一个demo,还请官方先查一下;
场景如下:现在A窗口为根窗口,A为手机桌面,B窗口为设置界面,C窗口为设置界面点击出现的一个非模态对话框,然而当创建非模态对话框C的时候,B窗口还可以响应消息,这个时候点击B的关闭按钮关闭掉B,在5.0里面C是没有被关闭的!!所以当再一次进入C界面,然后点击B的退出,程序就会崩溃,这个很紧急,希望可以在明天修复

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include <stdio.h>
#include <string.h>
HWND hMainWnd;

static LRESULT pwdlogin_ime_next_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
      printf("44444444 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_ime_next_hWnd = CreateWindowEx(CTRL_BUTTON,
        "44444444444",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        104,
        150, 0, 40, 40, hWnd, 0);
        break;
    }

case MSG_CLOSE:
    DestroyMainWindow (hWnd);
 MainWindowThreadCleanup (hWnd);
 break ;
 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static void pwdlogin_ime_deal(HWND hWnd, UINT dwId, WPARAM dwNc, LPARAM add_data)
{
HWND hWndParent = GetParent(hWnd);
DLGTEMPLATE stDlg;
switch (dwId)
{
case 102:

                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 250;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWndParent, pwdlogin_ime_next_proc, 0);
	     break;
	     
	     case 110:
	     SendMessage(hWndParent,MSG_CLOSE,0,0);
	     break;
	     

		}
return ;

}
static LRESULT pwdlogin_ime_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
      printf("33333 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_ime_hWnd = CreateWindowEx(CTRL_BUTTON,
        "333333333",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        102,
        50, 100, 105, 40, hWnd, 0);
        HWND pwdlogin_ime_hWnd2 = CreateWindowEx(CTRL_BUTTON,
        "=======",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        110,
        0, 0, 105, 40, hWnd, 0);
        SetNotificationCallback(pwdlogin_ime_hWnd2, (NOTIFPROC)pwdlogin_ime_deal);
        SetNotificationCallback(pwdlogin_ime_hWnd, (NOTIFPROC)pwdlogin_ime_deal);
        break;
    }
            case MSG_CLOSE:
    DestroyMainWindow (hWnd);
 MainWindowThreadCleanup (hWnd);
 break ;

 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static void pwdlogin_window_deal(HWND hWnd, UINT dwId, WPARAM dwNc, LPARAM add_data)
{
HWND hWndParent = GetParent(hWnd);
DLGTEMPLATE stDlg;
switch (dwId)
{
case 101:

                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 0;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWndParent, pwdlogin_ime_proc, 0);
	     break;

		}
return ;

}
static LRESULT pwdlogin_window_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
       printf("2222 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_window_hWnd = CreateWindowEx(CTRL_BUTTON,
        "222222",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        101,
        50, 100, 105, 40, hWnd, 0);
        SetNotificationCallback(pwdlogin_window_hWnd, (NOTIFPROC)pwdlogin_window_deal);
        break;
    }
    case MSG_CLOSE:
    printf("2222 recived close msg\n");
    DestroyMainWindow (hWnd);
 MainWindowThreadCleanup (hWnd);
 break ;
 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static LRESULT HelloWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message) {
    case MSG_CREATE:
    printf("111111 hwnd id is : %x\n",hWnd);
        hWnd = CreateWindowEx(CTRL_BUTTON,
        "11111111111",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_TRANSPARENT,
        100,
        50, 50, 105, 40, hWnd, 0);
        break;
    case MSG_COMMAND:
    	if(100 == wParam)
    	{	
    
    	    HWND    hWndParent = GetParent(hWnd);
    	    DLGTEMPLATE stDlg;
                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 0;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWnd, pwdlogin_window_proc, 0);
    	}
    	 break;
    case MSG_CLOSE:
     // DestroyMainWindow (hWnd);
      //PostQuitMessage (hWnd);
        break;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);

}

int MiniGUIMain (int argc, const char* argv[])
{
MSG Msg;

MAINWINCREATE CreateInfo;


CreateInfo.dwStyle = WS_VISIBLE | WS_CAPTION;
CreateInfo.dwExStyle = WS_EX_NONE;
CreateInfo.spCaption = "Hello";
CreateInfo.hMenu = 0;
CreateInfo.hCursor = GetSystemCursor(0);
CreateInfo.hIcon = 0;
CreateInfo.MainWindowProc = HelloWinProc;
CreateInfo.lx = 0;
CreateInfo.ty = 0;
CreateInfo.rx = 480;
CreateInfo.by = 272;
CreateInfo.iBkColor = COLOR_lightwhite;
CreateInfo.dwAddData = 0;
CreateInfo.hHosting = HWND_DESKTOP;
hMainWnd = CreateMainWindow (&CreateInfo);
printf("    HWND hMainWnd id is : %x \n",hMainWnd);
if (hMainWnd == HWND_INVALID)
    return -1;
ShowWindow(hMainWnd, SW_SHOWNORMAL);

while (GetMessage(&Msg, hMainWnd)) {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
}
MainWindowThreadCleanup (hMainWnd);
return 0;

}
#ifdef _MGRM_THREADS
#include <minigui/dti.c>
#endif

线程模式
操作是这样的:
先点击11111
再点击22222
在点击33333
再点击====
可以看到关闭了3333和44444的窗口
但是,继续点击22222
再点击33333
然后在点击22222
然后在点击====
出现崩溃

甚至多次点击2222和====或者随意点击按钮,只要多次点击====都会出现崩溃。

这段代码存在访问已释放内存的问题。将

SendMessage(hWndParent,MSG_CLOSE,0,0);

修改为使用 SendNotifyMessage 或者 PostMessage 函数(推荐使用前者),即可避免。

简单解释一下问题所在:按钮被单击时,系统将直接调用已注册的通知回调函数,回调函数返回后,按钮的代码仍然会继续执行。但因为在通知的回调函数中调用 SendMessage 发送了 MSG_CLOSE 消息,该消息的处理又将直接调用主窗口的回调函数来销毁按钮所在的主窗口,此时,按钮被随同主窗口一同被销毁,此后通知回调函数返回到按钮的窗口回调函数中做后续处理,但按钮已经被释放,于是导致程序崩溃。

因此,通常我们使用 SendNotifyMessage 或者 PostMessage 函数发送 MSG_CLOSE 消息,这样就可以让当前的消息处理先结束,然后在下个消息循环中再处理 MSG_CLOSE 消息。这可以避免出现上述问题或者其他重入导致的问题。

我们这边用的是SendNotifyMessage,稍等,我重新写一个demo,上面的有点问题

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include <stdio.h>
#include <string.h>
HWND hMainWnd;

static LRESULT pwdlogin_ime_next_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
      printf("44444444 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_ime_next_hWnd = CreateWindowEx(CTRL_BUTTON,
        "44444444444",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        104,
        150, 0, 40, 40, hWnd, 0);
        break;
    }

case MSG_CLOSE:
    DestroyMainWindow (hWnd);
 MainWindowThreadCleanup (hWnd);
 break ;
 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static void pwdlogin_ime_deal(HWND hWnd, UINT dwId, WPARAM dwNc, LPARAM add_data)
{
HWND hWndParent = GetParent(hWnd);
DLGTEMPLATE stDlg;
switch (dwId)
{
case 102:

                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 250;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWndParent, pwdlogin_ime_next_proc, 0);
	     break;
	     
	     case 110:
	     SendNotifyMessage(hWndParent,MSG_CLOSE,0,0);
	     break;
	     

		}
return ;

}
static LRESULT pwdlogin_ime_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
      printf("33333 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_ime_hWnd = CreateWindowEx(CTRL_BUTTON,
        "333333333",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        102,
        50, 100, 105, 40, hWnd, 0);
        HWND pwdlogin_ime_hWnd2 = CreateWindowEx(CTRL_BUTTON,
        "=======",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        110,
        0, 0, 105, 40, hWnd, 0);
        SetNotificationCallback(pwdlogin_ime_hWnd2, (NOTIFPROC)pwdlogin_ime_deal);
        SetNotificationCallback(pwdlogin_ime_hWnd, (NOTIFPROC)pwdlogin_ime_deal);
        break;
    }
            case MSG_CLOSE:
            printf("MSG_CLOSE\n");
         EndDialog(hWnd,0);
 break ;

 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static void pwdlogin_window_deal(HWND hWnd, UINT dwId, WPARAM dwNc, LPARAM add_data)
{
HWND hWndParent = GetParent(hWnd);
DLGTEMPLATE stDlg;
switch (dwId)
{
case 101:

                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 0;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    DialogBoxIndirectParam(&stDlg, hWndParent, pwdlogin_ime_proc, 0);
	     break;
	case 120:

               SendNotifyMessage(hWndParent,MSG_CLOSE,0,0);
	     break;


		}
return ;

}
static LRESULT pwdlogin_window_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
    case MSG_CREATE:
    {
       printf("2222 hwnd id is : %x\n",hWnd);
        HWND pwdlogin_window_hWnd = CreateWindowEx(CTRL_BUTTON,
        "222222",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        101,
        50, 100, 105, 40, hWnd, 0);
        HWND pwdlogin_window_hWnd_1= CreateWindowEx(CTRL_BUTTON,
        "close",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_NONE,
        120,
        100, 50, 80, 40, hWnd, 0);
        SetNotificationCallback(pwdlogin_window_hWnd, (NOTIFPROC)pwdlogin_window_deal);
        SetNotificationCallback(pwdlogin_window_hWnd_1, (NOTIFPROC)pwdlogin_window_deal);
        break;
    }
    case MSG_CLOSE:
    printf("2222 recived close msg\n");
    DestroyMainWindow (hWnd);
 MainWindowThreadCleanup (hWnd);
 break ;
 }
 
 return DefaultMainWinProc(hWnd, message, wParam, lParam);

}
static LRESULT HelloWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message) {
    case MSG_CREATE:
    printf("111111 hwnd id is : %x\n",hWnd);
        hWnd = CreateWindowEx(CTRL_BUTTON,
        "11111111111",
        WS_CHILD | WS_VISIBLE ,  
        WS_EX_TRANSPARENT,
        100,
        50, 50, 105, 40, hWnd, 0);
        break;
    case MSG_COMMAND:
    	if(100 == wParam)
    	{	
    
    	    HWND    hWndParent = GetParent(hWnd);
    	    DLGTEMPLATE stDlg;
                memset(&stDlg, 0, sizeof(stDlg));
	    stDlg.dwStyle = WS_VISIBLE | WS_CAPTION | WS_BORDER;
	    stDlg.dwExStyle = WS_EX_NONE;
	    stDlg.x = 0;
	    stDlg.y = 0;
	    stDlg.w = 200;
	    stDlg.h = 200;
	    stDlg.caption = "";
    	    CreateMainWindowIndirectParam(&stDlg, hWnd, pwdlogin_window_proc, 0);
    	}
    	 break;
    case MSG_CLOSE:
     // DestroyMainWindow (hWnd);
      //PostQuitMessage (hWnd);
        break;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);

}

int MiniGUIMain (int argc, const char* argv[])
{
MSG Msg;

MAINWINCREATE CreateInfo;


CreateInfo.dwStyle = WS_VISIBLE | WS_CAPTION;
CreateInfo.dwExStyle = WS_EX_NONE;
CreateInfo.spCaption = "Hello";
CreateInfo.hMenu = 0;
CreateInfo.hCursor = GetSystemCursor(0);
CreateInfo.hIcon = 0;
CreateInfo.MainWindowProc = HelloWinProc;
CreateInfo.lx = 0;
CreateInfo.ty = 0;
CreateInfo.rx = 480;
CreateInfo.by = 272;
CreateInfo.iBkColor = COLOR_lightwhite;
CreateInfo.dwAddData = 0;
CreateInfo.hHosting = HWND_DESKTOP;
hMainWnd = CreateMainWindow (&CreateInfo);
printf("    HWND hMainWnd id is : %x \n",hMainWnd);
if (hMainWnd == HWND_INVALID)
    return -1;
ShowWindow(hMainWnd, SW_SHOWNORMAL);

while (GetMessage(&Msg, hMainWnd)) {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
}
MainWindowThreadCleanup (hMainWnd);
return 0;

}
#ifdef _MGRM_THREADS
#include <minigui/dti.c>
#endif

你好,问题已经复现。

点击1111,
点击2222
点击3333,会出现4444,这个时候
在点击====
注意由于333是一个dialog窗口,所以用 EndDialog(hWnd,0);关闭了333,但是444并没有被关闭掉,最后点击close,在设备上会出现崩溃。
但是在ubuntu上模拟器会有保护
MainWindowCleanup: Unexpected call: Main window (0x55836c8b34c0) not destroyed yet! Please call DestroyMainualWindow() first
并不会出现崩溃,在设备上会出现崩溃。
原因就是,使用EndDialog(hWnd,0);关闭了333,但是作为333的子窗口444并没有被关闭

目前看来已修复,谢谢!

目前看来已修复,谢谢!

不客气,感谢您提交的复现代码!