C++ WinApi和C++;-状态栏不更新

C++ WinApi和C++;-状态栏不更新,c++,winapi,statusbar,C++,Winapi,Statusbar,我的状态栏在程序执行期间不刷新,我不知道为什么。首先是伪代码。我已经删除了大部分,只留下了想法 #include ... (many includes) using namespace std; #include "MyHeaderFile.hpp" LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); //here some global variables. Thereare

我的状态栏在程序执行期间不刷新,我不知道为什么。首先是伪代码。我已经删除了大部分,只留下了想法

#include ... (many includes)

using namespace std;

#include "MyHeaderFile.hpp"

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);

//here some global variables. Thereare more of them, I leave only teh important ones.

HWND g_hButtonStart;
MSG msg;

//----------------------------------- windows ------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{ WNDCLASSEX wc; 
  HWND hwnd;


  memset(&wc,0,sizeof(wc));
  wc.cbSize      = sizeof(WNDCLASSEX);
  wc.style           = 0;
  wc.lpfnWndProc     = WndProc;
  wc.cbClsExtra  = 0;
  wc.cbWndExtra = 0;
  wc.hInstance   = hInstance;
  wc.hCursor         = LoadCursor(NULL, IDC_ARROW);

  wc.hbrBackground = CreateSolidBrush(RGB(240,240,240));//(HBRUSH)(COLOR_WINDOW+1);
  wc.lpszMenuName  = NULL; 
  wc.lpszClassName = "WindowClass";
  wc.hIcon       = LoadIcon(NULL, IDI_APPLICATION);
  wc.hIconSm         = LoadIcon(NULL, IDI_APPLICATION);

    //window class register
  if(!RegisterClassEx(&wc))
  { MessageBox(NULL, "Rejestracja klasy okna nie powiodła się!","BMP->DXF: Błąd!",MB_ICONEXCLAMATION|MB_OK);
     return 0;
  }

  hwnd = CreateWindowEx(WS_EX_WINDOWEDGE,"WindowClass","BMP -> DXF",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  500, 
  275,
  NULL,NULL,hInstance,NULL);

  if(hwnd == NULL)
  { MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
     return 0;
  }

//group boxes, text boxes, buttons ...
//most important are the "START" button and the status bar: 

  g_hButtonStart = CreateWindowEx( 0, "BUTTON", "S T R T", WS_CHILD | WS_VISIBLE,   243, 133, 100, 30, hwnd, NULL, hInstance, NULL );

 ShowWindow( hwnd, nCmdShow );
  UpdateWindow( hwnd );


//status bar things  
  INITCOMMONCONTROLSEX icmc;
    icmc.dwSize = sizeof( INITCOMMONCONTROLSEX );
    icmc.dwICC = ICC_BAR_CLASSES;
    InitCommonControlsEx( & icmc );

    g_hStatusBar = CreateWindowEx( 0, STATUSCLASSNAME, NULL, SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd,( HMENU ) 200, hInstance, NULL );

    SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "some info" );
//status bar - end


    while(GetMessage(&msg, NULL, 0, 0))
    {   if (!IsDialogMessage(hwnd, &msg))
            {TranslateMessage(&msg); 
        DispatchMessage(&msg); }
    }

    return msg.wParam;
}

//messages
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{ bool ParameterWarning=false;
  string Info;

  switch(Message)
  {  case WM_CLOSE:
     {  DestroyWindow( hwnd );
     }
     break;

      case WM_DESTROY:
        {   PostQuitMessage(0);
            break;
        }

//here is the most important part of the code
        case WM_COMMAND:
        {   if(( HWND ) lParam == g_hButtonStart )
            {   //enabling and disabling some buttons, edit boxes etc.

                //some variables declarations and initializations...

                SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 1" );

                //opening the in file ...

                //reading file parameters and checking for errors ...

                SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 2" );

                //here some large calculations start, lasting for 30mins, for example; written in C++

                for(int N=0;N<one_of_the_variables;N++)
                {
                //calculations part 1; also writing to out file ...
                SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 3" );

                //calculations part 2; also writing to out file ...
                SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 4" );

                //calculations part 3; also writing to out file ...
                SendMessage( g_hStatusBar, SB_SETTEXT, 0,( LPARAM ) "message 5" );
                }



    //enabling and disabling some buttons, edit boxes etc. ...
    //closing the out file ...

    }               

    default:
            return DefWindowProc(hwnd, Message, wParam, lParam);

        }

    return 0;
}
#包括。。。(包括许多)
使用名称空间std;
#包括“MyHeaderFile.hpp”
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM);
//这里有一些全局变量。还有更多的,我只留下重要的。
HWND g_hButtonStart;
味精;
//-----------------------------------窗户------------------------------------------------------
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE HPPreInstance、LPSTR lpCmdLine、int nCmdShow)
{WNDCLASSEX wc;
HWND-HWND;
memset(&wc,0,sizeof(wc));
wc.cbSize=sizeof(WNDCLASSEX);
wc.style=0;
wc.lpfnWndProc=WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hCursor=LoadCursor(空,IDC_箭头);
wc.hbrBackground=CreateSolidBrush(RGB(240240));/(HBRUSH)(颜色窗口+1);
wc.lpszMenuName=NULL;
wc.lpszClassName=“WindowClass”;
wc.hIcon=LoadIcon(空,IDI_应用程序);
wc.hIconSm=LoadIcon(空,IDI_应用程序);
//窗口类寄存器
如果(!RegisterClassEx(&wc))
{消息框(空,“Rejestracja klasy okna nie powiodła się!”,“BMP->DXF:Błd!”,MB|u图标连接| MB|u OK);
返回0;
}
hwnd=CreateWindowEx(WS_EX_WINDOWEDGE,“WindowClass”,“BMP->DXF”,WS_可见| WS_重叠窗口,
CW_使用默认值,
CW_使用默认值,
500, 
275,
NULL,NULL,hInstance,NULL);
if(hwnd==NULL)
{MessageBox(NULL,“窗口创建失败!”,“错误!”,MB|U图标连接| MB|U OK);
返回0;
}
//分组框、文本框、按钮。。。
//最重要的是“开始”按钮和状态栏:
g_hButtonStart=CreateWindowEx(0,“按钮”,“S T R T”,WS_子项| WS|U可见,243、133、100、30、hwnd、NULL、hInstance、NULL);
显示窗口(hwnd、nCmdShow);
更新窗口(hwnd);
//状态栏的东西
INITCOMMONCONTROLSEX icmc;
icmc.dwSize=sizeof(INITCOMMONCONTROLSEX);
icmc.dwICC=ICC\u BAR\u类;
InitCommonControlsEx(和icmc);
g|hStatusBar=CreateWindowEx(0,状态类名称,NULL,SBARS_SIZEGRIP | WS|CHILD | WS|u可见,0,0,0,hwnd,(HMENU)200,hInstance,NULL);
SendMessage(g_hStatusBar,SB_SETTEXT,0,(LPARAM)“一些信息”);
//状态栏-结束
while(GetMessage(&msg,NULL,0,0))
{if(!IsDialogMessage(hwnd,&msg))
{翻译消息(&msg);
DispatchMessage(&msg);}
}
返回msg.wParam;
}
//信息
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{bool ParameterWarning=false;
字符串信息;
开关(信息)
{案例WM_关闭:
{窗口(hwnd);
}
打破
案例WM_销毁:
{PostQuitMessage(0);
打破
}
//下面是代码中最重要的部分
case WM_命令:
{if((HWND)lParam==ghbuttonstart)
{//启用和禁用某些按钮、编辑框等。
//一些变量声明和初始化。。。
SendMessage(g_hStatusBar,SB_SETTEXT,0,(LPARAM)“消息1”);
//正在打开文件中的。。。
//正在读取文件参数并检查错误。。。
SendMessage(g_hStatusBar,SB_SETTEXT,0,(LPARAM)“消息2”);
这里有一些大的计算开始,持续30min,例如用C++编写。
对于(int N=0;N而言,没有响应是问题的另一个症状。GUI应用程序需要频繁处理其消息队列。正是这种抽取消息队列的行为允许UI进行更新。长时间运行的任务会停止抽取消息队列,并导致您报告的各种问题


解决方案是频繁地抽取消息队列。不要在主线程中执行长时间运行的任务,因为这会阻止您为消息队列提供服务。将这些任务移动到单独的线程中。

谢谢。我是初学者,我从未编写过多线程应用程序。多线程是唯一的(最好的)方法吗解决方案?如果需要,是否需要多线程处理器来运行多线程应用程序?我希望我的应用程序也能在非常简单的计算机上运行。不,您不需要多核处理器。@初学者:不需要使用工作线程,但最好使用工作线程。如果不需要,则必须使用长时间运行的任务定期检查消息队列(查看
PeekMessage()
GetQueueStatus()
以检测挂起的消息,然后在循环中调用
PeekMessage()
,直到队列为空),或者重新写入长时间运行的任务,以便在消息队列的上下文中异步工作,这样它就不会被阻塞(做一些工作,给自己发一条消息来做更多的工作,再发一条消息来做更多的工作,等等).不是最好的选择,但可行。你必须做的远不止@Remy所说的。你还必须确保你的程序不会再次进入。这实际上比将计算转移到线程更难。David,@Remy。谢谢你提供了其他选项和对它们的评论。经过一些考虑,我决定最好选择最好的一开始就有解决方案。我将尝试多线程。