locked
修改系统来电显示的窗口标题,函数调用成功,为何显示的时候完全没有效果? RRS feed

  • 问题

  • 这是用远程spy查看到的WM6.5的窗口列表:

       HWND hh, h2;
       HWND hChild;
       hh = FindWindow( NULL, L"电话 - 拨入" );
       h2 = GetWindow( hh, GW_CHILD );
       h2 = GetWindow( h2, GW_CHILD );
       hChild = GetDlgItem( h2, 0x000059F1 );
       SetDlgItemText( h2, 0x000059F1, L"我靠,就是不行!" );


    程序运行之后,通过SPY++察看,窗口标题的确被修改了,但是我模拟一个来电之后,却发现完全没有效果。。。。有谁知道这是为何么。。。。

    补充,我是先模拟来电,等到来电窗口显示了之后才运行我的程序去修改的。。。


    da jia hao!
    2009年12月10日 11:35

答案

  • 我试了一下你的代码是可以的,可以修改的。我在模拟器上测试(wm6.0 professional)的。你可以用模拟器试一下。我的代码跟你一样,只是换了子窗口的ID。下面是我测试的代码:

     

    HRESULT RegisterWindows(HWND h)

    {

      HRESULT hr;

      NOTIFICATIONCONDITION nc;

     

    HREGNOTIFY g_NotifyPhoneCallCalling = NULL;

     

      nc.ctComparisonType = REG_CT_ANYCHANGE;

    nc.dwMask=SN_PHONEINCOMINGCALL_BITMASK;

      nc.TargetValue.dw   = 0;

     

     

      hr = RegistryNotifyWindow(

            SN_PHONEINCOMINGCALL_ROOT,

            SN_PHONEINCOMINGCALL_PATH,     // registry root to monitor

            SN_PHONEINCOMINGCALL_VALUE,    // registry value to monitor

                    h,     // callback to be called when bit changes

                            WM_USER,  

                            0,

                    &nc,

                    &g_NotifyPhoneCallCalling

                    );

     

     

      return hr;

    }

     

     

    LRESULT CIncommingCallTestDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

    {

          // TODO: Add your specialized code here and/or call the base class

          switch (message)

        {

     

          case WM_USER:

               

                HWND hh, h2;

       HWND hChild;

     

                Sleep(2000);

                HWND h=::FindWindow(NULL,L"Phone - Incoming");

               

                h2 = ::GetWindow( h, GW_CHILD );

                h2 = ::GetWindow( h2, GW_CHILD );

                hChild = ::GetDlgItem( h2, 0x00005A13 );

                //::SetDlgItemText( h2, 0x00005A13, L"my text");

                ::SetWindowText(hChild,L"my incoming call");

     

               

     

                SetForegroundWindow();

                break;

          }

     

          return CDialog::WindowProc(message, wParam, lParam);

    }

     



    如果模拟器可以,可能是OEM作了一些控制。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help

    • 已标记为答案 liubin 2009年12月18日 15:48
    2009年12月16日 3:33
    版主

全部回复

  • 有点不太明白你的意思,你想修改哪个窗口的文本?
    据我所知, hh = FindWindow( NULL, L"电话 - 拨入" );得到的是来电的提示窗口,而你用GW_CHILD来得到的是它的子窗口,而不是窗体FORM的文本,请检查是否是这个原因。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    2009年12月14日 9:11
    版主
  • 有点不太明白你的意思,你想修改哪个窗口的文本?
    据我所知, hh = FindWindow( NULL, L"电话 - 拨入" );得到的是来电的提示窗口,而你用GW_CHILD来得到的是它的子窗口,而不是窗体FORM的文本,请检查是否是这个原因。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help

    谢谢您的关注。从图中可以看到,“电话 - 拨入”这个窗口下有两个子窗口,而那个来电号码显示的窗口是第二个字窗口的子窗口,即红框里面框住的那个。它的ID通过SPY查看得知是0x00005F91,所以我就用第二个字窗口的句柄来查找这个现实来电号码的窗口:

    hChild = GetDlgItem( h2, 0x000059F1 );

    函数返回的hChild地址和SPY里面显示的完全一致,可是我调用SetWindowText却完全没有效果,不知道为何这个窗口的TEXT不能修改。。。。


    对了,我后来尝试了另外一个方法:
    HDC hdc = GetDC( hChild );
    DrawText( hdc, ..... );

    这样居然可以啊!只是有点可惜,不能处理它的WM_PAINT消息。。。。
    da jia hao!
    2009年12月14日 14:08
  • 补充,图中那个显示“我靠,就是不行”标题的窗口并不是显示来电号码的窗口,它上面那个才是,即“MS_PHONE_CALERTCONTACT”那个才是显示来电号码的窗口,对这个窗口调用SetWindowText完全无效。。。
    da jia hao!
    2009年12月14日 14:11
  • 还是有点不太明白,如果方便的话,能否把整个项目共享出来,大家看一下,或许能找到问题的原因。你可以写一个简单点的程序共享出来。
    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    2009年12月15日 3:14
    版主
  • 完整的代码如下:

       BOOL fResult;
       TCHAR sz[256];
       HWND hMain, hChild, h;
       hMain = FindWindow( NULL, L"电话 - 拨入" );
       h = GetWindow( hMain, GW_CHILD );
       h = GetWindow( h, GW_CHILD );

    //下面这个窗口就是“MS_PHONE_CALERTCONTACT”,在SPY里面双击那个窗口就可以得到这个ID
       hChild = GetDlgItem( h, 0x000059F1 );

    //对这个窗口调用SetWindowText,返回结果表示成功,但实际没有效果。。。
       fResult = SetWindowText( hChild, L"*********" );
       //fResult = SetDlgItemText( h, 0x000059F1, L"+++++++++" );


    //但是利用DrawText居然就可以在其上“写字”,神奇吧。。。。
       RECT rc;
       HDC hdc2;
       GetClientRect( hChild, &rc );
       hdc2 = GetDC( hChild );
       Rectangle( hdc2, rc.left, rc.top, rc.right, rc.bottom );
       LPCTSTR pp;
       pp = L"XX基金管理公司 孙总";
       DrawText( hdc2, pp, wcslen(pp), &rc, 0 );
       ReleaseDC( hChild, hdc2 );


    提示:用VS2005附带的“远程监视”可以看到很多信息。


    da jia hao!
    2009年12月15日 13:17
  • 我试了一下你的代码是可以的,可以修改的。我在模拟器上测试(wm6.0 professional)的。你可以用模拟器试一下。我的代码跟你一样,只是换了子窗口的ID。下面是我测试的代码:

     

    HRESULT RegisterWindows(HWND h)

    {

      HRESULT hr;

      NOTIFICATIONCONDITION nc;

     

    HREGNOTIFY g_NotifyPhoneCallCalling = NULL;

     

      nc.ctComparisonType = REG_CT_ANYCHANGE;

    nc.dwMask=SN_PHONEINCOMINGCALL_BITMASK;

      nc.TargetValue.dw   = 0;

     

     

      hr = RegistryNotifyWindow(

            SN_PHONEINCOMINGCALL_ROOT,

            SN_PHONEINCOMINGCALL_PATH,     // registry root to monitor

            SN_PHONEINCOMINGCALL_VALUE,    // registry value to monitor

                    h,     // callback to be called when bit changes

                            WM_USER,  

                            0,

                    &nc,

                    &g_NotifyPhoneCallCalling

                    );

     

     

      return hr;

    }

     

     

    LRESULT CIncommingCallTestDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

    {

          // TODO: Add your specialized code here and/or call the base class

          switch (message)

        {

     

          case WM_USER:

               

                HWND hh, h2;

       HWND hChild;

     

                Sleep(2000);

                HWND h=::FindWindow(NULL,L"Phone - Incoming");

               

                h2 = ::GetWindow( h, GW_CHILD );

                h2 = ::GetWindow( h2, GW_CHILD );

                hChild = ::GetDlgItem( h2, 0x00005A13 );

                //::SetDlgItemText( h2, 0x00005A13, L"my text");

                ::SetWindowText(hChild,L"my incoming call");

     

               

     

                SetForegroundWindow();

                break;

          }

     

          return CDialog::WindowProc(message, wParam, lParam);

    }

     



    如果模拟器可以,可能是OEM作了一些控制。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help

    • 已标记为答案 liubin 2009年12月18日 15:48
    2009年12月16日 3:33
    版主
  • 我试了一下你的代码是可以的,可以修改的。我在模拟器上测试(wm6.0 professional)的。你可以用模拟器试一下。我的代码跟你一样,只是换了子窗口的ID。下面是我测试的代码:

    HWND h=::FindWindow(NULL,L"Phone - Incoming");

               

                h2 = ::GetWindow( h, GW_CHILD );

                h2 = ::GetWindow( h2, GW_CHILD );

                hChild = ::GetDlgItem( h2, 0x00005A13 );

                //::SetDlgItemText( h2, 0x00005A13, L"my text");

                ::SetWindowText(hChild,L"my incoming call");



    如果模拟器可以,可能是OEM作了一些控制。
    Please remember to mark the replies as answers if they help and unmark them if they provide no help

    换ID的话我也成功了啊。但问题在于用户看见来电号码的是ID为0x000059F1的窗口,如果你对这个ID的窗口调用SetWindowText,是没有效果的。

    如果换成其他ID的窗口,是可以,但他们又不是用来显示来电号码的。。。。
    da jia hao!
    2009年12月16日 3:46
  • 我写的ID就是来电显示的ID, 窗口的class 是MS_PHONE_TEXT, 也就是你看到的0x000059F1。 可能不同的机器显示的不一样吧。希望你在模拟器上试一下。


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    2009年12月17日 3:11
    版主
  • 谢谢。

    我再次测试,确认:

    MS_PHONE_TEXT(窗口ID为:0x00005A13) 和 MS_PHONE_CALERTCONTACT(窗口ID为:0x000059F1) 是挨在一起的两个窗口

    缺省情况下,“MS_PHONE_TEXT”(窗口ID为:0x00005A13)会显示“来电”两个字

    而“MS_PHONE_CALERTCONTACT”(窗口ID为:0x000059F1)则会显示来电的号码

    如果对“MS_PHONE_TEXT”进行修改,有效果,但是对“MS_PHONE_CALERTCONTACT”进行修改则完全没有效果,它还是显示原来的号码。


    不过无论如何感谢微软的专家解答问题。我就将程序改为对“0x00005A13”这个窗口修改文字吧,0x000059F1那个窗口不鸟它了。。。


    da jia hao!
    2009年12月18日 15:43
  • 楼上各位好,是试了下,就0x00005A13 这个窗口可以修改内容,其他的似乎都不起作用

    及时用 DrawText来直接写,也是不行的啊


    另外我想修改OX00005E92 即上面 显示“35638”的窗口内容,似乎也修改不了啊,,帮帮忙咯

    2009年12月30日 6:55
  • 楼上各位好,是试了下,就0x00005A13 这个窗口可以修改内容,其他的似乎都不起作用

    及时用 DrawText来直接写,也是不行的啊


    另外我想修改OX00005E92 即上面 显示“35638”的窗口内容,似乎也修改不了啊,,帮帮忙咯

    楼上各位好,请问这个问题又解决的吗?我想修改OX000059E2 的功能,但是来电或者去电页面上无法显示。远程监视上却可以看到正确显示我要显示的内容,请问这个什么原因?

    万分感谢。

    2011年4月8日 8:32
  • 楼上各位好,是试了下,就0x00005A13 这个窗口可以修改内容,其他的似乎都不起作用

    及时用 DrawText来直接写,也是不行的啊


    另外我想修改OX00005E92 即上面 显示“35638”的窗口内容,似乎也修改不了啊,,帮帮忙咯

    楼上各位好,请问这个问题又解决的吗?我想修改OX000059E2 的功能,但是来电或者去电页面上无法显示。远程监视上却可以看到正确显示我要显示的内容,请问这个什么原因?

    万分感谢。

     

    WM6.5已经过时了,况且后来我发现这种做法根本不可行,用户实际拿到手的手机,都是被手机厂商定制过的,原始的来电界面根本不会显示,就算能修改用户也看不到。

    放弃吧!


    da jia hao!
    2011年4月12日 14:45