首页 > 解决方案 > WIN API - 选择按钮时程序卡住

问题描述

我正在使用 WINAPI 创建一个简单的软件,该软件从通过 USB 连接到计算机的传感器读取数据。在这个软件中,我正在实现一些功能,如读取模式、测试模式等。

我面临的问题是我在选择连续阅读按钮时卡住了,代码如下:

case WM_COMMAND:
    switch (wp)
    {  
    case START_BUTTON:
        printf("START_BUTTON"); 

        while(SendDlgItemMessage(hWnd,START_BUTTON,BM_GETCHECK ,TRUE,0)== BST_CHECKED)
        {
            char* var = USB_Read();   //Get data from the sensor
            SetWindowText(hLux, var); //Display the data

            if (SendDlgItemMessage(hWnd,START_BUTTON,BM_GETCHECK ,TRUE,0)!= BST_CHECKED) //Check if the botton is no longer selected
            break;
        }

        break;
    }
    break;

我知道问题出在while循环中,当我按下它时,所有程序都卡住了,只有数据正确显示,其他控件就像冻结一样。

问题是:我怎样才能连续显示数据并同时访问其他控件?

标签: c++windowswinapi

解决方案


您必须创建一个执行线程,在检查启动时读取 USB。因此,我们创建了一个在程序初始化时启动的线程,该线程连续运行并在每次找到选中的按钮时读取 USB。

现在在消息循环中,您只需选中或取消选中按钮。

DWORD WINAPI ThreadFunction( LPVOID lpParam )
{
    (void)lpParam;    //make happy compiler for unused variable

    while (TRUE)     //Once created the thread runs always
    {
        //If checked reads usb for each iteration
        if(SendDlgItemMessage(hWnd,START_BUTTON,BM_GETCHECK ,0,0)== BST_CHECKED)
        {
            char* var = USB_Read();   //Get data from the sensor
            SetWindowText(hLux, var); //Display the data
            Sleep(1);    //Why this? to don't have a furious CPU usage
        }
    }
}


.....

//Winmain
    DWORD dwThreadId;    //thread ID in case you'll need it
    //Create and start the thread
    CreateThread( 
                    NULL,           // default security attributes
                    0,              // use default stack size  
                    ThreadFunction, // thread function name
                    NULL,           // argument to thread function 
                    0,              // use default creation flags 
                    &dwThreadId);   // returns the thread identifier

......

case WM_COMMAND:
    switch (wp)
    {  
    case START_BUTTON:
        printf("START_BUTTON");
        if(SendDlgItemMessage(hWnd,START_BUTTON,BM_GETCHECK ,0,0)== BST_CHECKED)
            SendDlgItemMessage(hWnd,START_BUTTON,BM_SETCHECK ,BST_UNCHECKED, 0);
        else
            SendDlgItemMessage(hWnd,START_BUTTON,BM_SETCHECK ,BST_CHECKED, 0);
        break;
    }
    break;

编辑:我修改了程序以选中/取消选中单选按钮。

请注意Sleep函数的使用,最小值为 1ms。它用于将控制权交还给操作系统以平滑 CPU 使用率。如果在读取 USB 的函数中有足够的操作系统同步原语,则可以省略(检查 cpu 使用情况)。


推荐阅读