移植GCC应用程序,Windows游标停留在IDC_APPSTARTING上

时间:2011-09-22 23:30:25

标签: windows gcc cursor

我正在将一个应用程序(使用启动器存根)移植到Windows(使用MinGW GCC)。

这是我将用作演示问题的参考的最小示例。

#include <process.h>

int main(int argc, char *argv[])
{
    chdir("C:\appdir");
    spawnl(P_WAIT, "C:\appdir\app.exe", "C:\appdir\app.exe", NULL);
    return 0;
}

此启动程序存根编译如下:

gcc -O3 -o launcher.o -c launcher.c
gcc -mwindows -o launcher.exe launcher.o

运行launcher.exe时,它会正确执行app.exe,然后在终止之前等待它终止。

这意外的副作用是在launch.exe产生后,Windows光标进入箭头+沙漏模式约5秒。

直接运行app.exe时(通过命令提示符或双击它)不会发生这种情况。

我已经尝试将以下内容添加到上面的应用中,但没有成功(光标的行为与以前完全相同):

#include <windows.h>
SetCursor(LoadCursor(NULL, IDC_ARROW));

有趣的是,从命令提示符运行launcher.exe(而不是在资源管理器中双击)会导致光标正常运行。即,它只是闪烁到沙漏,几乎立即恢复正常。

如何抑制忙碌光标?或者至少可靠地回复,没有必须阻止?

2 个答案:

答案 0 :(得分:4)

SetCursor技巧无效,因为它会立即更改为IDC_APPSTARTING,因为系统正在响应WM_SETCURSOR消息。

Windows中的APPSTARTING游标或多或少地记录在STARTUPINFO结构页面中(请参阅有关STARTF_FORCEONFEEDBACK的说明)。

在那里它说你可以调用GetMessage()来摆脱反馈光标,但你似乎已经知道了。为什么你不想使用它?

关于从控制台窗口调用时的不同行为,这是有道理的。想想程序何时“输入空闲”:

  • 如果程序是Windows程序:第一个窗口创建并准备就绪(称为GetMessage)。
  • 如果程序是控制台程序:
    • 如果双击运行:只要它创建控制台窗口。
    • 如果从其他控制台运行:立即。

更新:尝试在main的最开头添加以下内容:

PostMessage(0, 0, 0, 0);
MSG msg;
GetMessage(&msg, 0, 0, 0);

答案 1 :(得分:0)

这很简单,罗德里戈指出你的方向正确。

Windows显示此光标以指示应用程序正在启动,并在应用程序开始其消息循环时将其关闭。您的启动器应用程序永远不会启动消息循环,因此Windows永远不会关闭游标。

所以,这就是你需要的:

#include <process.h>
#include <Windows.h>

void turn_off_the_starting_cursor()
{
  PostQuitMessage( 0 );

  MSG msg;
  BOOL bRet;
  while( (bRet = GetMessage( &msg, 0, 0, 0 )) != 0)
  { 
      if (bRet != -1)
      {
          TranslateMessage(&msg); 
          DispatchMessage(&msg); 
      }
  }
}

int main(int argc, char *argv[])
{
    turn_off_the_starting_cursor();

    chdir("C:\appdir");
    spawnl(P_WAIT, "C:\appdir\app.exe", "C:\appdir\app.exe", NULL);
    return 0;
}

这会将退出消息发布到消息队列,然后运行立即退出的循环。 Windows认为该应用已准备就绪。

  • 杰弗里