2014-01-10 43 views
2

我有一个无模式的Win32 API对话框作为状态框与LISTBOX在其中我打印IDE和MSSCCI提供程序之间的通信的一些信息。Win32 API对话框停止/冻结移动它

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

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

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

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

我试图在dialogboxes回调函数中捕获WM_MOVE和WM_MOVING,设置statusbox为活动窗口(见代码)。目前没有任何帮助。

我必须做什么,当用户移动它时,对话框不会冻结? 任何提示?

(顺便说一下,在调试的时候,我不能移动对话框,并在对话框的列表框中获取更新所有的时间和家长取得重绘太)

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

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); 
      : 
+0

int printedLength = 0; char tempChar = statusMessage [printedLength ...这是一些新的C++ 11魔法吗? – manuell

+0

我不确定我是否明白你的观点。 您是否喜欢在代码块的每个开始处都有变量初始化 { 部分代码 } ? 没有魔法,只是C. – Muzungu

+0

你是对的,我误解你的代码。 – manuell

回答

0

问题被该消息队列似乎不再被处理,由于吨o我的代码很长时间循环并与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, 

这可能不是一个非常优雅的解决方案,但所服务的目的。