我正在将一个应用程序(使用启动器存根)移植到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
(而不是在资源管理器中双击)会导致光标正常运行。即,它只是闪烁到沙漏,几乎立即恢复正常。
如何抑制忙碌光标?或者至少可靠地回复,没有必须阻止?
答案 0 :(得分:4)
SetCursor
技巧无效,因为它会立即更改为IDC_APPSTARTING,因为系统正在响应WM_SETCURSOR消息。
Windows中的APPSTARTING游标或多或少地记录在STARTUPINFO结构页面中(请参阅有关STARTF_FORCEONFEEDBACK的说明)。
在那里它说你可以调用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认为该应用已准备就绪。