惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
The GitHub Blog
The GitHub Blog
C
Check Point Blog
博客园_首页
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
F
Full Disclosure
Microsoft Security Blog
Microsoft Security Blog
爱范儿
爱范儿
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
G
GRAHAM CLULEY
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threat Research - Cisco Blogs
C
Cybersecurity and Infrastructure Security Agency CISA
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
博客园 - 司徒正美
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
云风的 BLOG
云风的 BLOG
Cisco Talos Blog
Cisco Talos Blog
Know Your Adversary
Know Your Adversary
雷峰网
雷峰网
V
V2EX - 技术
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Spread Privacy
Spread Privacy
罗磊的独立博客
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Security Affairs
SecWiki News
SecWiki News
Schneier on Security
Schneier on Security
O
OpenAI News
Jina AI
Jina AI
PCI Perspectives
PCI Perspectives
Cyberwarzone
Cyberwarzone
Y
Y Combinator Blog
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
I
InfoQ
D
Docker
P
Palo Alto Networks Blog
Recorded Future
Recorded Future
M
MIT News - Artificial intelligence
博客园 - Franky
B
Blog
Scott Helme
Scott Helme
博客园 - 叶小钗
D
DataBreaches.Net

博客园 - 啊夏

iOS6.0以后App对内存警告的处理 ios平台上一个由字节对齐问题导致的crash NSURLConnection 网络超时的那些事。 我看QQ与360的恩怨情仇 [转载]NSString+NSMutableString+NSValue+NSAraay用法汇总 一道求单向链表倒数第N个结点的算法题。 真正认识 realloc 的工作方式。 什么是最优秀的IT员工? 【转帖】有关次级贷的一个故事。很贴切 获取字符串的拼音首字母 [转载]关于const用法的 笔记记录 最大公约数-辗转相除法 向量的旋转算法---编程珠玑读书笔记。 activex 控件回调 javascript 一个“利”与“义”的故事。 重启PPC系统 GLDEF_C, LOCAL_C, GLREF_C 的含义 看看80的我们小时候都在玩些什么。 Carbide.c++ IDE的常用快捷键和技巧
详解百度手机输入法“搜索框”的秘密
啊夏 · 2010-04-15 · via 博客园 - 啊夏

   前两天换了新老板,新老板对百度很感兴趣,就要求我们开发跟百度手机输入自带的搜索框一样的一个“框”。

开始动工前,google了下(google现在不行了,转用bing吧),找到一篇文章。

“百度输入框的秘密” url: http://blog.csdn.net/pknife/archive/2010/01/06/5141282.aspx

先放两张效果图吧 

  

 建议先看上面这篇文章。下面的内容是具体实现的详解。 

     我们要实现的第一个目标:

 在homescreen 的菜单栏中央添加一个自定义的按钮。 

     背景资料:

       我们通过 SHFindMenuBar这个函数,将桌面顶层窗口的句柄传递进去后,能拿到桌面菜单栏的句柄。

       这时候,首先想到的就是直接使用api函数给菜单栏添加一个item。但是,当我们在wm的menubar上有3个菜单项的时候,那3个菜单项不会乖乖地以左中右的方式给我们进行排列。而是全部靠左依次排开。这显然不是我们想要的结果。

ok,上文提到的那篇blog 里面对“百度的搜索框”用spy已经分析的蛮清楚了。 现在我们把一些核心的信息提取出来。

  •  百度图标其实是个窗口,其父窗口是一个MS_SOFTKEY_CE_1.0类型的窗口 
  • SHFindMenuBar得到的只是menu_worker类型的窗口
  • MS_SOFTKEY_CE_1.0类型窗口是与menu_worker类型的窗口成对出现的。

ok,整理下思路。为了在主界面的menubar中间添加那么一个按钮。我们需要干下面的几件事情。       

  1. 找到桌面的菜单栏menubar,menu_worker类型的窗口
  2. 找到与桌面菜单栏menubar对应的MS_SOFTKEY_CE_1.0类型的窗口
  3. 在找到的MS_SOFTKEY_CE_1.0类型的窗口下,创建一个子窗口。
  4. 将子窗口移动到menubar的中间位置,并处理相关的按键和绘制消息。

好,对于上面的问题。第一个很好解决。

  HWND hwndMB = ::SHFindMenuBar(GetDesktopWindow());

第3点和第4点也没啥问题。这样难点就在第2点了。这里,我们注意到 MS_SOFTKEY_CE_1.0类型窗口是与menu_worker类型的窗口成对出现的。

那么他们之间有什么关系呢。还是使用我们伟大的spy大神(这里我就不截图了,有兴趣的可以自己去看看)。 我们会发现  menu_worker类型 窗口与他对应的MS_SOFTKEY_CE_1.0类型窗口所在的进程id是一样的。

ok,思路有了。 先查找到桌面menubar的句柄,然后得到他所在进程的编号。

遍历系统所有的顶层窗口,查找 MS_SOFTKEY_CE_1.0类型的窗口,然后将窗口的进程id跟 menubar的进程id进行比较,如果一致,则是我们所有查找的父窗口了。直接把关键代码放出来。

  代码

 1 
 2 void CreateMenuButtonOnDesktop()
 3 {
 4     HWND hwndMB = ::SHFindMenuBar(GetDesktopWindow());
 5     ::GetWindowThreadProcessId(hwndMB,&m_pID);//pID就是进程ID 
 6     EnumWindows(EnumWindowsProc,NULL);
 7 }
 8 
 9 BOOL   CALLBACK   EnumWindowsProc(HWND   hwnd,LPARAM   lParam)
10 {
11 
12     DWORD pID=0
13     ::GetWindowThreadProcessId(hwnd,&pID);//pID就是进程ID 
14 
15     if ((DWORD)m_pID == pID)
16     {
17 
18         TCHAR szClassName[128];
19         GetClassName(hwnd,szClassName,128);
20         if (wcscmp(szClassName,_T("MS_SOFTKEY_CE_1.0")) == 0)
21         {
22             
23             child_hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
24                 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, NULL, g_hInst, NULL);
25 
26             
27             if (!child_hWnd)
28             {
29                 return FALSE;
30             }
31 
32             int nWidth = 36;
33             int nHeight = 20;
34             RECT rc;
35             GetWindowRect(hwnd,&rc);
36             MoveWindow(child_hWnd, (rc.right- nWidth)/2, (rc.bottom - rc.top - nHeight)/2 , nWidth, nHeight, FALSE);
37 
38             ShowWindow(child_hWnd, WM_SHOWWINDOW);
39             UpdateWindow(child_hWnd);
40             return FALSE;
41         }
42     }
43     return TRUE;
44 }

 第4步,这里就不花时间来写了。

我们要实现的第2个目标。

  创建一个非模态的对话框 

这个跟本篇文章的核心思路关系不大,在这里也不细说了。相信大家都能轻松搞定。

至此,我们完成了一个跟百度一个的桌面menubar中间的按钮。 有空可能会把symbian版本的也写下。(symbian 相关的网上的资料相对比较多。呵呵)