Win32 API对话框在移动时停止/冻结

时间:2014-01-10 08:15:39

标签: winapi dialog

我有一个无模块的Win32 API对话框作为状态框,其中包含一个LISTBOX,其中我打印了IDE和MSSCCI提供程序之间通信的一些信息。

一切正常(状态消息逐行打印并滚动),除非我作为IDE用户触摸状态对话框并尝试移动它。

然后状态更新冻结(点击状态对话框几次,“无响应”出现在标题栏中),并随之显示父应用程序(IDE)。

该程序似乎仍在后台运行(我也登录到“可见”进度的文件)。

当任务(从回购中获取多个文件)完成时,对话框不会被销毁,但会被应用程序隐藏。稍后当新任务启动时,会再次显示对话框,新打印的任务的状态消息将被打印并再次滚动,就像没有发生任何事情一样。

我试图在对话框回调函数中捕获WM_MOVE和WM_MOVING,将状态框设置为活动窗口(参见代码)。到目前为止没有任何帮助。

当用户移动对话框时,我该怎么做? 任何提示?

(顺便说一句,在调试时,我无法移动对话框,对话框中的列表框也会一直更新,而父级也会重新绘制)

这里有一些代码(文件处理循环):

    pool = svnApiSvnIface.fp_svn_pool_create_ex(masterPool, NULL);
for(i=0; i<nFiles; i++)
{
    WaspLoggerLogPrintf(0, "%s - Processing: '%s' \n",
                        __FUNCTION__,
                        StripFilename(lpFileNames[i]));
    UpdateWindow(hwndParent);
    SetActiveWindow (hwndStatusBox);

    PrintMesgStatusBox("CheckFileStatus: for %s", StripFilename(lpFileNames[i]));
    revison.kind = svn_opt_revision_unspecified;
             :

这里是PrintMesgStatusBox()函数的一些代码:

    if(UseStatusBox())
{
    int lbIndex = 0;
    int length = vsprintf(statusMessage, format, args);
    int printedLength = 0;
    while((printedLength + STATUSBOX_LINE_LENGTH) < length)
    {
        char tempChar = statusMessage[printedLength + STATUSBOX_LINE_LENGTH];
        statusMessage[printedLength + STATUSBOX_LINE_LENGTH] = '\0';
        SendDlgItemMessage(hwndStatusBox, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)&statusMessage[printedLength]);
        statusMessage[printedLength + STATUSBOX_LINE_LENGTH] = tempChar;
        printedLength += STATUSBOX_LINE_LENGTH;
    }
    SendDlgItemMessage(hwndStatusBox, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)&statusMessage[printedLength]);

    //AUTOSCROLL
    lbIndex = SendDlgItemMessage(hwndStatusBox, IDC_LIST1, LB_GETCOUNT, 0, 0) - 1;
    //Scroll to the newest item (put lbIndex to the top of the lb)
    SendDlgItemMessage(hwndStatusBox, IDC_LIST1, LB_SETTOPINDEX, lbIndex, 0);

    //redraw
    UpdateWindow(hwndStatusBox);
            :

1 个答案:

答案 0 :(得分:0)

问题在于,由于我的代码循环并且长时间与SVN服务器通信,似乎不再处理消息队列。 由于我无法控制IDE实现,所以我必须在我的dll中执行它。

我在循环中实现了一个消耗和分配对话框消息的函数(分别是所有消息)。

如果全部或仅使用了对话框消息,结果会有所不同:

仅使用对话框消息:每次SVN通信后对话框都会更新,这会导致用户操作的UI响应相当不稳定。但IDE菜单保持可访问状态。

使用所有消息:对用户的UI响应相对平稳。但可以访问IDE菜单,IDE可以关闭或启动其他操作。这是不受欢迎的。

因此我只使用对话框消息。

一些代码(函数处理消息):

 void ProcessMessages(HWND hWnd, BOOLEAN peekHwndMsgsOnly)
 {
     MSG msg;
 HWND peekHwnd = NULL;

 if(peekHwndMsgsOnly)
 {
    peekHwnd = hWnd;
 }

     while(PeekMessage(&msg, peekHwnd, 0, 0, PM_REMOVE))
    {
        if(!IsDialogMessage(hWnd, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}

最初阻止消息处理的循环:

for(i=0; i<nFiles; i++)
{
    /*
    WaspLoggerLogPrintf(0, "%s - Processing: '%s' \n",
                        __FUNCTION__,
                        StripFilename(lpFileNames[i]));
    */

    PrintMesgStatusBox("CheckFileStatus: for %s", StripFilename(lpFileNames[i]));
    revison.kind = svn_opt_revision_unspecified;
    youngest = SVN_INVALID_REVNUM;
    internalfileName = svnApiSvnIface.fp_svn_dirent_internal_style(lpFileNames[i], pool);
    if (updateFromRepo) { PrintMesgStatusBox("    Retrieving repo status..."); }
    UpdateWindow(hwndParent);
    ProcessMessages(hwndStatusBox, TRUE);

    rtn = svnApiSvnIface.fp_svn_client_status4( &youngest,                              // svn_revnum_t *result_rev,
                                            internalfileName,                           // const char *path, 
                                            &revison,                                   // const svn_opt_revision_t *revision, 

这可能不是一个非常优雅的解决方案,但正在达到目的。