草庐IT

c - Windows 8.1 : only works if dummy printf is called 上的 WndProc 异常行为

coder 2024-06-17 原文

UPDATE: @JonathanPotter solved my problem on a comment (see below). Apparently I should have called DefWindowProc on WndProc. If I call it instead of the dummy printf, everything works. But I'll keep the question open because I'm still curious to know why the printf itself also made it work in the first place.

我正在编写一个程序,当笔记本盖子打开/关闭时它会执行一些操作。有一个不可见的窗口可以监视 WM_POWERBROADCAST 消息并正确处理它们。还有一个控制台(用于调试目的)。

该程序在 Windows 10 上运行良好,然后我去另一台运行 Windows 8.1 的机器上对其进行测试,但该程序未捕获 WM_POWERBROADCAST 消息。

奇怪的是:

  • 如果我在 WndProc 的开头添加一个dummy printf会收到消息

我准备了一个 MCVE ,以防万一有人想尝试重现它(如下)。注意在 WndProc 的开头有一个 printf 注释。

场景 1:printf 行保持注释

如果我在 Windows 10 上运行程序,这是我在运行时得到的结果(无需关闭盖子,只需运行程序):

Power broadcast message received

但如果我在 Windows 8.1 上运行它,我什么也得不到(即使我关闭/打开盖子)。

场景2:printf行没有注释

这是我在 Windows 10 和 8.1 上得到的:

MSG: 36
MSG: 129
MSG: 131
MSG: 1
MSG: 799
MSG: 536
Power broadcast message received
MSG: 49273

(除了 MSG: 49273,它没有出现在 Windows 8.1 上,但似乎不相关)。

为什么会这样?

更多信息:

  • 两个 Windows 都是 64 位的
  • 编译器:MinGW 64 5.1.0 (x86_64-posix-seh-rev0)

这是 MCVE :

#include <windows.h>
#include <stdio.h>

int WndProc(HWND hWnd, UINT message,
            WPARAM wParam, LPARAM lParam)
{
    //printf("MSG: %d\n", message);

    if (message == WM_POWERBROADCAST)
    {
        printf("Power broadcast message received\n");
    }
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    WNDCLASS wc;
    memset(&wc, 0, sizeof(WNDCLASS));
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.lpszClassName = L"Test";

    RegisterClass(&wc);

    HWND hWnd = CreateWindow(wc.lpszClassName, NULL,
        0, 0, 0, 0, 0, NULL, NULL,
        hInstance, NULL);

    RegisterPowerSettingNotification(hWnd, &GUID_LIDSWITCH_STATE_CHANGE, 0);

    ShowWindow(hWnd, SW_HIDE);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

提前致谢。

最佳答案

问题是 WndProc 返回了一些东西而你没有返回任何东西。虚拟 printf 的奇怪行为是由于 printf 返回的工件遗留在 eax 寄存器中,导致它成为函数返回。

当添加默认值时:return DefWindowProc(...),这满足大多数消息的返回,因此您的 WM_POWERBROADCAST 突然开始工作。

最可能的失败解释是您的非初始化返回变成了 WM_NCCREATE 或 WM_CREATE 的失败代码,因此没有创建窗口。

关于c - Windows 8.1 : only works if dummy printf is called 上的 WndProc 异常行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32212468/

有关c - Windows 8.1 : only works if dummy printf is called 上的 WndProc 异常行为的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  5. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  6. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  7. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  8. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  9. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  10. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

随机推荐