如何在应用程序级别忽略系统消息? (WM_SettingChange / WM_WinIniChange)

时间:2014-05-22 08:29:56

标签: windows c++builder

当用户在Windows区域设置中更改日期格式时,我们的应用程序出现异常。 (是的,解决方案是解决不良行为 - 这不是重点。)

更改设置会将WM_SETTINGCHANGE消息广播到所有应用程序。我们试图通过忽略此消息来避免我们的问题,并保持日期格式(现在,作为修补程序)。

无论我做什么,TMonthCalendar组件仍然会更改其格式,以及TDateTimePicker使用TMonthCalendar作为其弹出窗口。

我尝试过(所有结果都相同):

  • 覆盖TForm::WndProc()

    void __fastcall TfrmMainWindow::WndProc( TMessage & msg )
    {
      if( msg.Msg == WM_SETTINGCHANGE )  return;  // ignore
    
      TForm::WndProc( msg );
    }
    
  • 使用Application->HookMainWindow( hookWindowsMessage );
  • 设置挂钩
  • 设置TApplication.UpdateFormatSettings = false;
  • 设置Application->OnEvent = onApplicationEvent;以捕获所有事件......但遗憾的是,此特定情况属于" OnMessage仅接收发布到消息队列的消息,而不是直接使用Windows API SendMessage函数发送的消息"规则。

似乎覆盖WndProc()几乎是一个好主意,只是它只影响那个窗口,而不是整个应用程序。我认为这是Application->HookMainWindow()的用途,但显然不是。

任何人都知道如何解决或解决这个问题?

1 个答案:

答案 0 :(得分:0)

正如Cody Gray在上面的评论中所述,问题不是消息处理,而是使用Win32 API日历的TMonthCalendar组件,因此应用程序上下文中运行。

但是,对于所有其他组件(即。TDateTimePicker的行编辑)和内部全局变量(如ShortDateFormat等), 可能忽略格式更改,如下所示:

class TfrmMainWindow : public TForm
{
public:
  __fastcall TfrmMainWindow( TComponent * Owner )
    : TForm( Owner )
    {
      Application->HookMainWindow( hookWindowsMessage );
    }

  __fastcall ~TfrmMainWindow()
    {
      Application->UnhookMainWindow( hookWindowsMessage );
    }

private:
  bool __fastcall hookWindowsMessage( TMessage & msg )
    {
      if( msg.Msg == WM_SETTINGCHANGE )
      {
        String sLParam( (char *)msg.LParam );

        // Check for Region Settings change (not Desktop background etc.)
        if( sLParam.LowerCase() == "intl" )
        {
          return true;  // ignore message
        }
      }

      return false;  // handle message as usual
    }
};

来源:
"Trapping Messages Sent to an Application"

"TMonthCalendar displays dates according to the system locale (ignoring the BiDiMode setting)."

"The Win32 API provides a control used to select dates on a colorful calendar. The dates used and the way they display are based on the Regional Settings of the Control Panel."