<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Yonsm.NET]]></title> 
<link>HTTP://WWW.Yonsm.NET/index.php</link> 
<description><![CDATA[SHARE YONSM'S IDEAS]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Yonsm.NET]]></copyright>
<item>
<link>HTTP://WWW.Yonsm.NET/read.php?516</link>
<title><![CDATA[在 iPhone/iPad 中随意修改数字键盘按钮]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Wed, 01 Sep 2010 19:00:55 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?516</guid> 
<description>
<![CDATA[ 
	一、起因<br/><br/>iPhone 的键盘，特别是数字键盘，往往不能满足程序的输入需要。最典型的例子就是在数字键盘上添加一个“.”，用来输入小数点。安装 iPhone SDK 官方的观点，如果要使用小数点键盘，那只好使用数字和符号键盘，但那样没个按键很小，且不需要的按键太多。<br/><br/><br/>二、现有方案<br/><br/>针对这种情况，最早的解决方案，请参考这里：<a href="http://www.cnblogs.com/mac_arthur/archive/2010/05/18/1738363.html" target="_blank">http://www.cnblogs.com/mac_arthur/archive/2010/05/18/1738363.html</a>。使用的是 以下代码来检测一个 Notification。<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">[[NSNotificationCenter defaultCenter] addObserver:self <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selector:@selector(addCustomKeyBoardButton)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name:UIKeyboardWillShowNotification<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; object:nil];</div></div><br/><br/>这种方法，在 iOS 4.0 后失效了，原因有两个，一是UIKeyboard<span style="color: #FF0000;">Will</span>ShowNotification的时候，键盘根本没有创建出来;另外，Class Name 也被外包了一层，叫做UIPeripheralHostView。<br/><br/>于是又有了一种改进的方案，请看这里：<a href="http://www.neoos.ch/news/46-development/54-uikeyboardtypenumberpad-and-the-missing-return-key" target="_blank">http://www.neoos.ch/news/46-development/54-uikeyboardtypenumberpad-and-the-missing-return-key</a>。主要的改进是在UIKeyboard<span style="color: #FF0000;">Did</span>ShowNotification的通知消息中来修改键盘。但正如作者所说，这里有个不完美的情况，只能等键盘动画显示完成之后，才能添加显示我们的东西，视觉效果不好。<br/><br/>三、改进方案<br/><br/>经过试验，找到一个比较完美的方案：在 UITextField 的becomeFirstResponder和resignFirstResponder中修改键盘。<br/><br/>定以一个类，假如叫做 KBCustomTextField : UITextField，在这个类中加入一下代码：<br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>//<br/>- (BOOL)becomeFirstResponder<br/>&#123;<br/>&nbsp;&nbsp;BOOL ret = [super becomeFirstResponder];<br/>&nbsp;&nbsp;[self modifyKeyView:@"NumberPad-Empty" display:@"." represent:@"." interaction:@"String"];<br/>&nbsp;&nbsp;return ret;<br/>&#125;<br/><br/>//<br/>- (BOOL)resignFirstResponder<br/>&#123;<br/>&nbsp;&nbsp;BOOL ret = [super resignFirstResponder];<br/>&nbsp;&nbsp;[self modifyKeyView:@"NumberPad-Empty" display:nil represent:nil interaction:@"None"];<br/>&nbsp;&nbsp;return ret;<br/>&#125;<br/></div></div><br/><br/>modifyKeyView 的实现可以参看附件。我使用的是循环查找UIKBKeyView类，这是Apple 的 Private API（私有API的声明可以在这里找：<a href="http://github.com/kennytm/iphone-private-frameworks/tree/master/UIKit/" target="_blank">http://github.com/kennytm/iphone-private-frameworks/tree/master/UIKit/</a>），不确信能否通过 App Store 的审核：）<br/><br/>更近一步地，我完善了一下 KBCustomTextField，通过这个类，非常方便地就可以做到自定义输入键盘：<br/><br/><a href="attachment.php?fid=45">点击这里下载文件</a><br/><br/>1. 使用小数点和数字键盘：非常简单，只要在 IB 中把 UITextField 的类改成KBCustomTextField，就OK了，不用一行代码，效果如下图：<br/><a href="HTTP://WWW.Yonsm.NET/attachment.php?fid=42" target="_blank"><img src="HTTP://WWW.Yonsm.NET/attachment.php?fid=42" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>2. 在键盘的按键上添加一个文字按钮（并指定处理动作）：设置KBCustomTextField.kbDelegate，实现这两个函数即可：<br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>// [Yonsm] Handle keyboard show<br/>- (void)keyboardShow:(KBCustomTextField *)sender<br/>&#123;<br/>&nbsp;&nbsp;[sender addCustomButton:@"NumberPad-Empty" title:@"DONE" target:self action:@selector(onButton:)];<br/>&#125;<br/><br/>// [Yonsm] Handle keyboard hide<br/>- (void)keyboardHide:(KBCustomTextField *)sender<br/>&#123;<br/>&nbsp;&nbsp;[sender delCustomButton:@"NumberPad-Empty"];<br/>&#125;<br/></div></div><br/><a href="HTTP://WWW.Yonsm.NET/attachment.php?fid=43" target="_blank"><img src="HTTP://WWW.Yonsm.NET/attachment.php?fid=43" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/>3. 更近一步地，这两个 Delegate 函数中，你只要通过 name 来查找到想要修改的 UIKBKeyView，就可以随便修改它。name 可以通过 KBCustomTextField 的#define _LOG_KEY_VIEW来列出所有的按键名称。name 为 nil 则找任何的 UIKBKeyView（可以用他的 .superview 来找到整个键盘View，做更多的处理）。<br/><a href="HTTP://WWW.Yonsm.NET/attachment.php?fid=44" target="_blank"><img src="HTTP://WWW.Yonsm.NET/attachment.php?fid=44" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/><br/><br/>下面是 iPhone 数字键盘的前面10个按键（后面忘了打出来了：）<br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>Found View: UIPeripheralHostView<br/>Found View: UIKeyboardAutomatic<br/>Found View: UIKeyboardImpl<br/>Found View: UIKeyboardLayoutStar<br/>Found View: UIKBKeyplaneView<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-1&nbsp;&nbsp;representedString=1&nbsp;&nbsp;displayString=1&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=String&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-2&nbsp;&nbsp;representedString=2&nbsp;&nbsp;displayString=2/ABC&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=String&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-3&nbsp;&nbsp;representedString=3&nbsp;&nbsp;displayString=3/DEF&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=String&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-4&nbsp;&nbsp;representedString=4&nbsp;&nbsp;displayString=4/GHI&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=String&nbsp;&nbsp;displayRowHint=Row2<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-6&nbsp;&nbsp;representedString=6&nbsp;&nbsp;displayString=6/MNO&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=String&nbsp;&nbsp;displayRowHint=Row2<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-7&nbsp;&nbsp;representedString=7&nbsp;&nbsp;displayString=7/PQRS&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=String&nbsp;&nbsp;displayRowHint=Row3<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-8&nbsp;&nbsp;representedString=8&nbsp;&nbsp;displayString=8/TUV&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=String&nbsp;&nbsp;displayRowHint=Row3<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-9&nbsp;&nbsp;representedString=9&nbsp;&nbsp;displayString=9/WXYZ&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=String&nbsp;&nbsp;displayRowHint=Row3<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=NumberPad-Empty&nbsp;&nbsp;representedString=&nbsp;&nbsp;displayString=&nbsp;&nbsp;displayType=NumberPad&nbsp;&nbsp;interactionType=None&nbsp;&nbsp;displayRowHint=Row4</div></div><br/><br/>代码对 iPad 也有效，当然 Key Name 和&nbsp;&nbsp;Type 不一样，下面是 iPad 数字键盘的Log：<br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">Found View: UIPeripheralHostView<br/>Found View: UIKeyboardAutomatic<br/>Found View: UIKeyboardImpl<br/>Found View: UIKeyboardLayoutStar<br/>Found View: UIKBKeyplaneView<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-1&nbsp;&nbsp;representedString=1&nbsp;&nbsp;displayString=1&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-2&nbsp;&nbsp;representedString=2&nbsp;&nbsp;displayString=2&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-3&nbsp;&nbsp;representedString=3&nbsp;&nbsp;displayString=3&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-4&nbsp;&nbsp;representedString=4&nbsp;&nbsp;displayString=4&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-5&nbsp;&nbsp;representedString=5&nbsp;&nbsp;displayString=5&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-6&nbsp;&nbsp;representedString=6&nbsp;&nbsp;displayString=6&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-7&nbsp;&nbsp;representedString=7&nbsp;&nbsp;displayString=7&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-8&nbsp;&nbsp;representedString=8&nbsp;&nbsp;displayString=8&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-9&nbsp;&nbsp;representedString=9&nbsp;&nbsp;displayString=9&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Digit-0&nbsp;&nbsp;representedString=0&nbsp;&nbsp;displayString=0&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row1<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Hyphen-Minus&nbsp;&nbsp;representedString=-&nbsp;&nbsp;displayString=-&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Solidus&nbsp;&nbsp;representedString=/&nbsp;&nbsp;displayString=/&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row2<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Colon&nbsp;&nbsp;representedString=:&nbsp;&nbsp;displayString=:&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row2<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Semicolon&nbsp;&nbsp;representedString=;&nbsp;&nbsp;displayString=;&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Left-Parenthesis&nbsp;&nbsp;representedString=(&nbsp;&nbsp;displayString=(&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Right-Parenthesis&nbsp;&nbsp;representedString=)&nbsp;&nbsp;displayString=)&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Primary-Currency-Sign&nbsp;&nbsp;representedString=$&nbsp;&nbsp;displayString=$&nbsp;&nbsp;displayType=DynamicString&nbsp;&nbsp;interactionType=String-Popup<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Ampersand&nbsp;&nbsp;representedString=&&nbsp;&nbsp;displayString=&&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Commercial-At&nbsp;&nbsp;representedString=@&nbsp;&nbsp;displayString=@&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Full-Stop&nbsp;&nbsp;representedString=.&nbsp;&nbsp;displayString=.&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Comma&nbsp;&nbsp;representedString=,&nbsp;&nbsp;displayString=,&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;displayRowHint=Row3<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Question-Mark&nbsp;&nbsp;representedString=?&nbsp;&nbsp;displayString=?&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Exclamation-Mark&nbsp;&nbsp;representedString=!&nbsp;&nbsp;displayString=!&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Apostrophe&nbsp;&nbsp;representedString='&nbsp;&nbsp;displayString=’&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Quotation-Mark&nbsp;&nbsp;representedString="&nbsp;&nbsp;displayString=”&nbsp;&nbsp;displayType=String&nbsp;&nbsp;interactionType=String-Popup&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Delete-Key&nbsp;&nbsp;representedString=Delete&nbsp;&nbsp;displayString=delete&nbsp;&nbsp;displayType=Delete&nbsp;&nbsp;interactionType=Delete&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Return-Key&nbsp;&nbsp;representedString=<br/>interactionType=Return&nbsp;&nbsp;displayRowHint=Row2<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Undo-Key&nbsp;&nbsp;representedString=undo&nbsp;&nbsp;displayString=undo&nbsp;&nbsp;displayType=Command&nbsp;&nbsp;interactionType=Undo&nbsp;&nbsp;displayRowHint=Row3<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=More-Key&nbsp;&nbsp;representedString=More&nbsp;&nbsp;displayString=more&nbsp;&nbsp;displayType=More&nbsp;&nbsp;interactionType=More&nbsp;&nbsp;displayRowHint=Row4<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Unlabeled-Space-Key&nbsp;&nbsp;representedString=&nbsp;&nbsp; displayString=&nbsp;&nbsp;displayType=Space&nbsp;&nbsp;interactionType=Space&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=More-Key&nbsp;&nbsp;representedString=More&nbsp;&nbsp;displayString=more&nbsp;&nbsp;displayType=More&nbsp;&nbsp;interactionType=More&nbsp;&nbsp;displayRowHint=Row4<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Dismiss-Key&nbsp;&nbsp;representedString=Dismiss&nbsp;&nbsp;displayString=Dismiss&nbsp;&nbsp;displayType=Dismiss&nbsp;&nbsp;interactionType=Dismiss&nbsp;&nbsp;<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Shift-Key&nbsp;&nbsp;representedString=Shift&nbsp;&nbsp;displayString=shift&nbsp;&nbsp;displayType=Shift&nbsp;&nbsp;interactionType=Shift&nbsp;&nbsp;displayRowHint=Row3<br/>Found View: UIKBKeyView<br/>&nbsp;&nbsp;name=Shift-Key&nbsp;&nbsp;representedString=Shift&nbsp;&nbsp;displayString=shift&nbsp;&nbsp;displayType=Shift&nbsp;&nbsp;interactionType=Shift&nbsp;&nbsp;displayRowHint=Row3</div></div>
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?507</link>
<title><![CDATA[CFLite for VC:移植 Core Foundation 到 Visual C++ 中]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Wed, 19 May 2010 06:12:05 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?507</guid> 
<description>
<![CDATA[ 
	Core Foundation 是 Apple 的开源基础组件，提供了各种基础设施，如 PLIST 处理、XML parser、String、Array、Dictionary 等等<br/><br/>在处理 Apple 平台的某些东西（比如处理 Mac OSX、iPhone、iPad 的 plist 文件）的时候可能需要用到 Apple 的 Core Foundation。当然在 Xcode 中可以很轻易使用这些东西（内置的），但在 Win32 中却有些麻烦（有时候可能会在 Windows 下处理点什么）。<br/><br/>网上搜索 CFLite （<a href="http://www.kjams.com/wiki/Code/CFLite" target="_blank">http://www.kjams.com/wiki/Code/CFLite</a>） 可以找到一个网站，精简了 CoreFoundation 并提供了些 DLL l以便在 Win32 中使用它——但，这个东西太老了（2008年的更新），以至于都不支持 binary plist 这些 iPhone 中最常用的 plist 格式的读写。<br/><br/>正好想弄个 iPhone/iPad&nbsp;&nbsp;PLIST 的命令行编辑工具，所以自己移植了一下 Core Foundation。参看附件中的 CFLite 目录：<br/><br/>1. CoreFoundation：头文件，从“<a href="http://www.opensource.apple.com/" target="_blank">http://www.opensource.apple.com/</a>”中下载的 10.6.2 的版本（10.6.3尚未提供）。<br/><br/>2. Redist：运行库，从 iTunes 安装后的“C:&#92;Program Files&#92;Common Files&#92;Apple&#92;Apple Application Support”中打包的运行时DLL。本来想把 Core Foundation 的 C 文件编译一下做成静态库的，折腾了好久没搞定，暂时用用 40M 的庞大的 运行库吧。<br/><br/>3. CoreFoundation.lib，从 Redist&#92;CoreFoundation.dll 中手工制作的LIB文件，制作方法如下：<br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>&nbsp;&nbsp;1、在 Visuall Studio Command Prompt 执行：&nbsp;&nbsp; <br/>&nbsp;&nbsp;dumpbin&nbsp;&nbsp; /exports&nbsp;&nbsp; CoreFoundation.dll&nbsp;&nbsp; >&nbsp;&nbsp; CoreFoundation.def&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;2、编辑&nbsp;&nbsp; yourdll.def&nbsp;&nbsp; 文件，使之格式与.def文件格式一致。比如：&nbsp;&nbsp; <br/>&nbsp;&nbsp;LIBRARY CoreFoundation&nbsp;&nbsp;<br/>&nbsp;&nbsp;EXPORTS<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fn1;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fn2;&nbsp;&nbsp; <br/>&nbsp;&nbsp;3、在命令行执行：&nbsp;&nbsp; <br/>&nbsp;&nbsp;lib&nbsp;&nbsp; /def:CoreFoundationl.def&nbsp;&nbsp; /machine:i386&nbsp;&nbsp; /out:CoreFoundationl.lib<br/></div></div><br/><br/>如果需要其他的DLL中的功能，可以类推。<br/><br/>4. 其他 .h 文件，GNU 兼容的 头文件。<br/><br/>其他的文件是 PLCMD 的东西，PLED.cpp 可以认为是一个 PLIST 读写的 Sample 吧：）<br/><br/><a href="/big/CFLite.zip">点击这里下载文件</a><br/>
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?473</link>
<title><![CDATA[[转载]OpenMP 编程指南]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Wed, 29 Jul 2009 08:25:10 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?473</guid> 
<description>
<![CDATA[ 
	进入多核时代后，必须使用多线程编写程序才能让各个CPU核得到利用。在单核时代，通常使用操作系统提供的API来创建线程，然而，在多核系统中，情况发生了很大的变化， 如果仍然使用操作系统API来创建线程会遇到一些问题。具体来说，有以下三个问题：<br/><br/>1）CPU核数扩展性问题<br/><br/>多核编程需要考虑程序性能随CPU核数的扩展性，即硬件升级到更多核后，能够不修改程序就让程序性能增长，这要求程序中创建的线程数量需要随CPU核数变化，不能创建固定数量的线程，否则在CPU核数超过线程数量上的机器上运行，将无法完全利用机器性能。虽然通过一定方法可以使用操作系统API创建可变化数量的线程，但是比较麻烦，不如OpenMP方便。<br/><br/>2）方便性问题<br/><br/>在多核编程时，要求计算均摊到各个CPU核上去，所有的程序都需要并行化执行，对计算的负载均衡有很高要求。这就要求在同一个函数内或同一个循环中，可能也需要将计算分摊到各个CPU核上，需要创建多个线程。操作系统API创建线程时，需要线程入口函数，很难满足这个需求，除非将一个函数内的代码手工拆成多个线程入口函数，这将大大增加程序员的工作量。使用OpenMP创建线程则不需要入口函数，非常方便，可以将同一函数内的代码分解成多个线程执行，也可以将一个for循环分解成多个线程执行。<br/><br/>3）可移植性问题<br/><br/>目前各个主流操作系统的线程API互不兼容，缺乏事实上的统一规范，要满足可移植性得自己写一些代码，将各种不同操作系统的api封装成一套统一的接口。OpenMP是标准规范，所有支持它的编译器都是执行同一套标准，不存在可移植性问题。<br/><br/>综上所述，在多核编程中，使用OpenMP就很有必要，下面列出以前发表在我的CSDN博客中的OpenMP文章，供大家参考。<br/><br/>1、OpenMP并行程序设计（一）<br/><br/>介绍OpenMP程序在并行计算时的效率，在双核CPU上效率增加了整整一倍。 <a href="http://blog.csdn.net/drzhouweiming/archive/2006/08/28/1131537.aspx" target="_blank">阅读全文</a><br/><br/>2、OpenMP并行程序设计（二）<br/><br/>1、fork/join并行执行模式的概念 2、OpenMP指令和库函数介绍 3、parallel 指令的用法 4、for指令的使用方法 5 sections和section指令的用法。<a href="http://blog.csdn.net/drzhouweiming/archive/2006/09/04/1175848.aspx" target="_blank">阅读全文</a><br/><br/>3、OpenMP中的数据处理子句<br/><br/>本文主要介绍了OpenMP中的private、firstprivate、lastprivate、threadprivate、reduction、copyin、copyprivate等数据处理子句的用法。 <a href="http://blog.csdn.net/drzhouweiming/archive/2008/01/10/2033276.aspx" target="_blank">阅读全文</a><br/><br/>4、OpenMP中的任务调度<br/><br/>本文主要介绍了OpenMP中任务调度子句schedule的使用方法。<a href="http://blog.csdn.net/drzhouweiming/archive/2007/10/26/1844762.aspx" target="_blank">阅读全文</a><br/><br/>5、OpenMP创建线程中的锁及原子操作性能比较<br/><br/>主要比较了原子操作，Windows CriticalSection， OpenMP库带的锁在单任务运行情况下和多任务运行情况下的性能情况，在多核CPU上，多任务的锁竞争花费的时间是单任务时的锁运行花费时间的18倍。锁竞争带来的效率下降完全出乎意料之外，由此也可见多核编程和单核多线程编程是有很大区别的。 <a href="http://blog.csdn.net/drzhouweiming/archive/2007/07/13/1689853.aspx" target="_blank">阅读全文</a><br/><br/>6、OpenMP程序设计的两个小技巧<br/><br/>讲述了如何动态设置线程数量以适应硬件和软件的扩展性，如何将嵌套循环并行化的技巧。 <a href="http://blog.csdn.net/drzhouweiming/archive/2008/05/23/2472454.aspxx" target="_blank">阅读全文</a><br/><br/> <br/><br/>上面列出的这些OpenMP知识，属于初步的入门知识，如果需要进一步深入掌握OpenMP或者了解其实现原理，则需要看更多的参考文献。下面列出我写的《多核计算与程序设计》一书的第3章OpenMP程序设计中的参考文献，供需要深入掌握的人参考。其中的文献【2】讲解了OpenMP的实现原理。<br/><br/>【1】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ananth Grama, Anshul Gupta，“并行计算导论”，张武等译，机械工业出版社，2005.01<br/><br/>【2】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Barbara Chapman， “How OpenMP is Compiled ”，<a href="http://cobweb.ecn.purdue.edu/ParaMount/iwomp2008/documents/chapman-underthehood" target="_blank">http://cobweb.ecn.purdue.edu/ParaMount/iwomp2008/documents/chapman-underthehood</a><br/><br/>【3】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bruce McMillin等，“Parallel Algorithm Fundamentals and Analysis”，<a href="http://citeseer.ist.psu.edu/mcmillin93parallel.html" target="_blank">http://citeseer.ist.psu.edu/mcmillin93parallel.html</a><br/><br/>【4】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Common Language Infrastructure (CLI) Partitions I to VI <a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf" target="_blank">http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf</a><br/><br/>【5】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Introduction to OpenMP，A Directive-based API for Parallel Processing on Shared-memory Computers，<a href="http://scv.bu.edu/documentation/tutorials/OpenMP/" target="_blank">http://scv.bu.edu/documentation/tutorials/OpenMP/</a><br/><br/>【6】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Michael J. Quinn, “MPI与OpenMP并行程序设计”，陈文光等译，清华大学出版社，2004.10<br/><br/>【7】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mitsuhisa Sato, Shigehisa Satoh, Kazuhiro Kusano and Yoshio Tanaka, “Design of OpenMP Compiler for an SMP Cluster”,<br/><br/><a href="http://www.hpcs.is.tsukuba.ac.jp/~msato/pdplab/papers/ewomp99.pdf" target="_blank">http://www.hpcs.is.tsukuba.ac.jp/~msato/pdplab/papers/ewomp99.pdf</a><br/><br/>【8】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MSDN帮助材料<br/><br/>ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_vclang/html/652414c5-78ed-4b7f-8283-1a9fe4c5e78d.htm&nbsp;&nbsp;<br/><br/>【9】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Omni OpenMP compiler, <a href="http://phase.hpcc.jp/omni/home.html." target="_blank">http://phase.hpcc.jp/omni/home.html.</a><br/><br/>【10】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenMP2.0规范&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.openmp.org/" target="_blank">http://www.openmp.org/</a><br/><br/>【11】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenMP2.5规范&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.openmp.org/" target="_blank">http://www.openmp.org/</a><br/><br/>【12】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenMP: Simple, portable, scalable SMP Programming, <a href="http://www.OpenMP.org." target="_blank">http://www.OpenMP.org.</a><br/><br/>【13】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Rudolf Eigenmann and Timothy G. mattson. “OpenMP tutorial, part 2: Advanced OpenMP.”， <a href="http://www.cise.ufl.edu/research/ParallelPatterns/sc01-omp-tut-advanced.ppt." target="_blank">http://www.cise.ufl.edu/research/ParallelPatterns/sc01-omp-tut-advanced.ppt.</a><br/><br/>【14】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ruud van der Pas ，“An Introduction Into OpenMP”，<a href="http://www.nic.uoregon.edu/iwomp2005/iwomp2005_tutorial_openmp_rvdp.pdf" target="_blank">http://www.nic.uoregon.edu/iwomp2005/iwomp2005_tutorial_openmp_rvdp.pdf</a><br/><br/>【15】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sanjiv Shah, Grant Haab, Paul Petersen, & Joe Throop，“Flexible Control Structures for Parallelism in OpenMP”，<a href="http://www.it.lth.se/ewomp99/papers/grant.pdf" target="_blank">http://www.it.lth.se/ewomp99/papers/grant.pdf</a><br/><br/>【16】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Shameem Akhter等，“多核程序设计技术－通过软件多线程提升性能”，电子工业出版社，2007.03<br/><br/>【17】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Special issue on OpenMP and its applications. Scientific Programming, 11(2),2003.<br/><br/>【18】&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y. Charlie Hu, Honghui Lu, Alan L. Cox, and Willy Zwaenepoel. “OpenMP for networks of SMPs”，In Proceedings of 13th International Parallel Processing Symposium and 10th Symposium on Parallel and Distributed Processing, page 302-310. IEEE Computer Society, 1999.<br/><br/><span style="color: #FF0000;"><br/>转自：<a href="http://software.intel.com/zh-cn/blogs/2009/04/20/openmp-2/" target="_blank">http://software.intel.com/zh-cn/blogs/2009/04/20/openmp-2/</a><br/>作者：Zhouweiming 周伟明<br/></span>
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?472</link>
<title><![CDATA[终于搞定了 BlackBerry 9530 EVDO 上网（手机+电脑Modem）]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Thu, 16 Jul 2009 05:24:02 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?472</guid> 
<description>
<![CDATA[ 
	朋友弄了张430多块钱的电信CDMA上网账号，想在黑莓 9530 中上网，并用作电脑的Modem上网，几经折腾，终于搞定了。<br/><br/>在此记录一下，有需要的人可以尝试。<br/><br/><br/><strong>1. 获取A-KEY、IMSI、ESN</strong><br/><br/><span style="color: #FF0000;">A-KEY</span>：16位的HEX数字（如E886************），用于用户鉴权，只能从电信内部人士得到（网上都这样说，暂且就这样听吧）。<br/><br/><span style="color: #FF0000;">ESN</span>： 是16位的HEX数字（如80******），这个可以从UIM卡中读取（用CDMA Workshop 3.41，官方下载Dem版本）。或者……把在9530中拨打 ##000000 进入查看手机的ESN，给电信内部人士，叫他重新绑定你的手机ESN到IMSI（和A-KEY？）（我就是这种方法，因为我写入UIM卡的ESN到手机失败了——注意，初始情况下，手机的ESN不是UIM卡的ESN）。<br/><br/><span style="color: #FF0000;">IMSI</span>： 是15位的数字（如4600309********），手机号码的内部形式，这个应该可以从UIM卡中读取（不过我是另寻途径搞得）。同时IMSI也是EVDO的上网AN/AAA账号，其实可以打10000咨询服务人员。<br/><br/>EVDO上网密码：打10000咨询，服务小姐可能啥也不知道，就问15位的账号（就是IMSI）和16位的密码。<br/><br/><br/><strong>2. 写入 A-KEY、IMSI、ESN 到 9530</strong><br/><br/><br/><span style="color: #FF0000;">IMSI</span>：9530中拨打##000000，进入工程模式，在IMSI_S一栏输入 IMSI然后Save即可（需重启，请耐心等待）。<br/><br/><span style="color: #FF0000;">A-KEY</span>：上面的方法中，貌似也能写入A-KEY，但好像不会成功的。能成功的方法，见这里：<a href="http://bbs.maxpda.com/thread-196588-1-4.html" target="_blank">http://bbs.maxpda.com/thread-196588-1-4.html</a>。<br/><br/>用到的工具 CDMA Workshop 3.4.1 Demo（注意：网上的其他版本的破解版有病毒）:<br/><a href="http://www.cdma-ware.com/workshop.html" target="_blank">http://www.cdma-ware.com/workshop.html</a><br/><br/><br/><span style="color: #FF0000;">ESN</span>：见这里：<a href="http://honeyhan.cn/200906/18_1023.html" target="_blank">http://honeyhan.cn/200906/18_1023.html</a>，但是，我尝试了无数次，失败了！只好另寻途径，把自己手机的ESN给电信“内部人士”，叫他帮忙用收集的ESN绑定一个新的IMSI（和A-KEY），所以我就没改变手机的ESN了。<br/><br/>到此，应该能打电话了。<br/><br/><br/><strong>3. 导入ServiceBook，支持手机上网</strong><br/><br/><br/>具体操作：<a href="http://bbs.pgcw.com.cn/dispbbs.asp?boardid=67&id=30495&page=0&move=next" target="_blank">http://bbs.pgcw.com.cn/dispbbs.asp?boardid=67&id=30495&page=0&move=next</a><br/><br/>Service Book 我用的是这里的：<a href="http://www.52blackberry.com/viewthread.php?tid=252900" target="_blank">http://www.52blackberry.com/viewthread.php?tid=252900</a><br/><br/>WinLoader：<a href="http://chinawrc.blog.enorth.com.cn/article/242417.shtml" target="_blank">http://chinawrc.blog.enorth.com.cn/article/242417.shtml</a><br/><br/>这时候，用手机的浏览器能上网了，不过是 CDMA1X 的，速度比较慢。<br/><span style="color: #FF0000;">我这里，依然有个问题：自带的浏览器上网，如果久了，会突然不能上网，Google 地图等其他软件均不能上网，拔电池重启又行了。不知何故（刷151OS之前手机 中国移动 EDGE 上网一直都很稳定的，不过Service Book 不一样）。不过下文的用作电脑的调制解调器方式，很稳定，很久都OK。</span><br/><br/><br/><strong>4. 导入PRL，支持EVDO</strong><br/><br/>我用到的 PRL 文件从这里下载：<a href="http://www.52blackberry.com/viewthread.php?tid=252900" target="_blank">http://www.52blackberry.com/viewthread.php?tid=252900</a><br/><br/>操作方法：<a href="http://www.52blackberry.com/viewthread.php?tid=214199" target="_blank">http://www.52blackberry.com/viewthread.php?tid=214199</a><br/><br/>补充说明：上面的操作方法语焉不详，我补充一下，必须用QPST 2.7.264 或更新的版本，以下QPST操作在更改数据之前，请首先 Read From Phone 一下。<br/> 1) QPST Configuration 好端口后，在 Service Programming 中，ROAM页面，导入PRL文件，自动重启;<br/>&nbsp;&nbsp;2) PPP Config 页面，点击 Um，User Password 都填入“card”，并勾上Req PW enc，点“Write to Phone”（不确定这步骤可能不需要，就当有多不坏菜吧）<br/> 3) 在PPP Config 页面，点击AN，User 输入你的IMSI，密码输入EVDO的密码（前面说过的，拨打10000号可以问到，分别是15位和16为），并勾上Req PW enc，点“Write to Phone”（这部关键）。<br/> 4) 其他操作，看这里吧 <a href="http://www.52blackberry.com/viewthread.php?tid=214199" target="_blank">http://www.52blackberry.com/viewthread.php?tid=214199</a>。<br/> 5) Home SID 从这里查：<a href="http://bbs.pcpop.com/090114/4816107.html" target="_blank">http://bbs.pcpop.com/090114/4816107.html</a><br/><br/><br/>用到的工具 QPST 2.7.264 （注意：必须是这个版本或者更高版本，否则不能写入ROAM PRL和PPP的AN/AAA）：<br/><a href="http://www.shuaji.net/down/soft/dopod/2009/2-12/down09212973261.shtml" target="_blank">http://www.shuaji.net/down/soft/dopod/2009/2-12/down09212973261.shtml</a><br/><br/><br/>这时候，手机亦应能EVDO上网了，确认方法（手机启动后，一直显示 1xev，上网后也不改变，如果又变成1x，说明账号密码不对）<br/><br/><br/><strong>5. 设置拨号连接，支持用作电脑 Modem</strong><br/><br/>1. 把手机接上电脑中，控制面板调制解调器中，选择黑莓“标准调制解调器”，属性，调制解调器初始命令（作用是启用手机的调制解调器模式）：<br/>AT+CGDCONT=1,"ip","ctnet"<br/><br/>2) 新建拨号连接，设置如下（杭州的设置，其他地方应该也是这样？）：<br/><br/>号码：#777<br/>用户名：ctnet@mycdma.cn<br/>密码：vnet.mobi<br/><br/>然后拨号，可以看到手机顶部出现“调制解调器模式启用”的文字，小写的 1xev 也变成大写 1XEV 了。到电信网站上下载点东西看看，速度超级快（300KB/s），不过到其他网站上则可能慢一些（限速啦？）<br/><br/><br/><br/><strong>6. 评论</strong><br/><br/>电脑上下载中国电信的东西，速度竟然能达到300KB/s，下载Yonsm.NET的东西稳定保持在150KB/s以上，电信的3G才是真正的3G！TD这种垃圾，继续爱国去吧！<br/><br/>
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?461</link>
<title><![CDATA[解决 Windows 7 开始菜单和任务栏图标错误地方法]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Mon, 04 May 2009 01:57:31 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?461</guid> 
<description>
<![CDATA[ 
	如果安装或运行一个第三方软件（如飞信之类的，系统默认会自动刷新桌面图标），这时我们新建的开始菜单和任务栏快捷方式的图标很容易变成错误的了。Windows 7 Build 7000 到 7100 似乎一直存在这样的问题。<br/><br/>解决办法是用一些系统维护软件重建图标缓存，或者手动操作：<br/><br/>先把这个文件删除，然后手工：新建文本文件，改名成iconcache.db，属性改为：只读。或者执行如下命令：<br/><br/><div class="code"><br/>CD /D %USERPROFILE%&#92;AppData&#92;Local&#92;<br/>ATTRIB -s -r -h IconCache.db<br/>COPY /Y NUL IconCache.db<br/>ATTRIB +r IconCache.db<br/></div><br/><br/>重启电脑，进入桌面后，再把这个文件只读属性去掉！（如果不去掉只读属性，无法缓存图标）<br/><br/>
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?460</link>
<title><![CDATA[把 Opera 做成完全绿色免安装版]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Sat, 02 May 2009 19:48:31 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?460</guid> 
<description>
<![CDATA[ 
	发现 Opera 在网页浏览方面还是很有优势的，一直以来都因为这个鸟软件不能绿色安装（特指放在任意目录那种）一直没用。趁着前两天改 Google Maps 的精神，今天又操刀了一下：<br/><br/><br/>零、首先提剪切 Application Data 下面的 Opera （可能是 Opera 9.51 Beta 之类的名称）目录到 Opera 程序文件所在目录，我们的目的是使它能绿色正常运行。<br/><br/><br/>一、查找 SHGetSpecialFolderPath(...0x1A...) 这个地方是获取 Application Data路径的。找到后改为：<br/><br/>IDA ARM Code:<br/><br/><div class="code"><br/>.text:00569FB4 sub_569FB4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; CODE XREF: sub_71B08+24p<br/>.text:00569FB4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STR&nbsp;&nbsp;&nbsp;&nbsp; LR, &#91;SP,#-4&#93;!<br/>.text:00569FB8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDR&nbsp;&nbsp;&nbsp;&nbsp; R1, =unk_6448A0<br/>.text:00569FBC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp; R2, #0x104<br/>.text:00569FC0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp; R0, #0<br/>.text:00569FC4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetModuleFileNameW<br/>.text:00569FC8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp; R2, #0<br/>.text:00569FCC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDR&nbsp;&nbsp;&nbsp;&nbsp; R3, =unk_6448A0<br/>.text:00569FD0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADD&nbsp;&nbsp;&nbsp;&nbsp; R3, R3, R0,LSL#1<br/>.text:00569FD4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRH&nbsp;&nbsp;&nbsp;&nbsp;R2, &#91;R3,#-0x16&#93;<br/>.text:00569FD8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp; R0, #1<br/>.text:00569FDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDR&nbsp;&nbsp;&nbsp;&nbsp; R1, =unk_63A32C<br/>.text:00569FE0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDR&nbsp;&nbsp;&nbsp;&nbsp; R0, =unk_6448A0<br/>.text:00569FE4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDR&nbsp;&nbsp;&nbsp;&nbsp; LR, &#91;SP&#93;,#4<br/>.text:00569FE8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; loc_569F6C<br/>.text:00569FE8 ; End of function sub_569FB4</div><br/><br/>下面的VC ARM Code可作参考:<br/><br/><br/><div class="code">; 6&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp; TCHAR tzPath&#91;MAX_PATH&#93;;<br/>; 7&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp; UINT nLen = GetModuleFileName(NULL, tzPath, MAX_PATH);<br/><br/>&nbsp;&nbsp;00008&nbsp;&nbsp;e3a02f41&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r2, #0x41, 30<br/>&nbsp;&nbsp;0000c&nbsp;&nbsp;e28d1000&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r1, sp, #0<br/>&nbsp;&nbsp;00010&nbsp;&nbsp;e3a00000&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r0, #0<br/>&nbsp;&nbsp;00014&nbsp;&nbsp;eb000000&nbsp;&nbsp; bl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetModuleFileNameW<br/><br/>; 8&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp; tzPath&#91;nLen - 11&#93; = 0;<br/><br/>&nbsp;&nbsp;00018&nbsp;&nbsp;e28d3000&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3, sp, #0<br/>&nbsp;&nbsp;0001c&nbsp;&nbsp;e0833080&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r3, r3, r0, lsl #1<br/>&nbsp;&nbsp;00020&nbsp;&nbsp;e3a02000&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r2, #0<br/>&nbsp;&nbsp;00024&nbsp;&nbsp;e14321b6&nbsp;&nbsp; strh&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2, &#91;r3, #-0x16&#93;<br/><br/>; 9&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp; return 1;<br/><br/>&nbsp;&nbsp;00028&nbsp;&nbsp;e3a00001&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r0, #1</div><br/><br/>二、另外，该死的Opera团队，乱七八糟的版本多不说，程序中我竟然还有很多硬编码，Opera的老大还有脸说UCWeb技术没有他们好，靠！Win95 时期菜鸟程序员的垃圾风格。我们还需要把一处 rdata.xxxxxxx 中的 &#92;Application Data 硬编码字符串的引用指向上面的 unk_6448A0。<br/><br/><br/>三、经过上面两步，Opera 已经能够运行了，继续完美它。opera.ini 中帮助文件路径改成你所希望的路径。<br/><br/><div class="code">&#91;User Prefs&#93;<br/>Default URL=http://www.google.com/<br/>Home URL=http://www.google.com/<br/>Help URL=&#92;Application Data&#92;Opera 9.5 Beta&#92;help&#92;en&#92;-&gt;&#92;Application Data</div>&nbsp;&nbsp;改成你的Opera目录<br/><br/><br/>四、注册表项目需要导入到注册表中<br/><br/><br/><div class="code">&#91;HKEY_LOCAL_MACHINE&#92;Software&#92;Opera&#92;Info&#93;<br/>&quot;SplashscreenWgtManPortrait Generic&quot;=&quot;&#92;&#92;Storage Card&#92;&#92;Tools&#92;&#92;Opera&#92;&#92;splash_wgtman_225x150.bmp&#92;&#92;&quot;<br/>&quot;SplashProgressFPS Generic&quot;=dword:0000000a<br/>&quot;SplashWgtProgressImage Generic&quot;=&quot;&#92;&#92;Storage Card&#92;&#92;Tools&#92;&#92;Opera&#92;&#92;line.png&quot;<br/>&quot;SplashProgressHeight Generic&quot;=dword:00000008<br/>&quot;SplashscreenPortrait Generic&quot;=&quot;&#92;&#92;Storage Card&#92;&#92;Tools&#92;&#92;Opera&#92;&#92;splash_225x150.bmp&quot;<br/>&quot;SplashProgressImage Generic&quot;=&quot;&#92;&#92;Storage Card&#92;&#92;Tools&#92;&#92;Opera&#92;&#92;line.png&quot;<br/>&quot;SplashscreenWgtManLandscape Generic&quot;=&quot;&#92;&#92;Storage Card&#92;&#92;Tools&#92;&#92;Opera&#92;&#92;splash_wgtman_225x150.bmp&#92;&#92;&quot;<br/>&quot;SplashscreenLandscape Generic&quot;=&quot;&#92;&#92;Storage Card&#92;&#92;Tools&#92;&#92;Opera&#92;&#92;splash_225x150.bmp&quot;</div><br/><br/>五、设置的地址也是硬编码的，需要改过来，否则无法进入设置了：用十六进制编辑器查找：<br/><br/><br/><div class="code">file://localhost/Application Data/Opera 9.5 Beta/Settings/settings.htm</div><br/><br/>替换成你的实际路径（如果长度不够了，改成文件系统的路径，比如我改成：<br/><br/><br/><div class="code">&#92;Storage Card&#92;Tools&#92;Opera&#92;Opera 9.5 Beta&#92;Settings&#92;settings.htm</div><br/><br/>六、最后，皮肤选择，如果是QVGA，默认则可。如果是VGA，建议使用 standard_skin_VGA.zip，改名成 standard_skin.zip<br/><br/>还有，opera.ini 中看一下，还需要把缩放参数变一下，具体自己看。VGA和QVGA的缩放参数不一样。<br/><br/><div class="code">&#91;Adaptive Zoom&#93;<br/><br/>;For VGA<br/>;Maximum Zoom=190<br/>;Minimum Zoom=190<br/><br/>Maximum Zoom=100<br/>Minimum Zoom=70</div><br/><br/>也可以输入 opera:config 可以进入详细设置（在User Pref下面），自己慢慢体会，可以开启 Turbo 方式，似乎可以翻墙了。<br/><br/><br/>好麻烦啊，还不如安装版？以后再弄个CeleSetup的自动脚本就方便了。<br/><br/>OK，完成收工，好麻烦。上面只是给出一个可行的方法。顺便放上 Opera 9.51 Beta IOICN 清凉汉化版的修改版作为成果，支持 PPC5/6 VGA/QVGA，需要的请下载。其中第三、四、五步如果和我不一样的目录，请自己替换。（以后我会整合和 一键安装软件包 中）<br/><br/><br/><span style="color: #C0C0C0;">By Yonsm 2009.05.03 4:29 AM, My LP is sleeping soundly:)</span><br/><br/><br/><a href="/big/Opera.zip">点击这里下载文件</a><br/><br/><br/>
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?456</link>
<title><![CDATA[Windows Mobile SP/PPC 中 Menu Bar 使用完美方案]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Sat, 25 Apr 2009 03:15:22 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?456</guid> 
<description>
<![CDATA[ 
	在SP/PPC写过MenuBar代码的人可能都知道，AygShell 中 Menu Bar 的设计真是无话说，各种系统（SP、PPC、2003、5.0）功能差异不一致，导致编程特别不方便。比如 SP2003 中不能使用 SHCMBF_HMENU 标记，PPC 5.0/6.0 终不能使用 SHCMBM_GETMENU，SP/PPC 2003中不能使用 TBIF_BYINDEX 来操作按钮，等等。<br/><br/>在别扭与愤懑中，用着MenuBar都过了4年了。终于整理出了一套相对比较完美的方案。先做一些假定：<br/><br/>1.&nbsp;&nbsp;如果我们的代码用 SP2003 SDK 编译，则必须支持 SP/PPC 2003/5 (这里5.0的意思包含5.0和之后的版本，因为5以后都比较完美统一)。<br/>2.&nbsp;&nbsp;用 PPC2003 SDK 编译的话，必须要支持 PPC 2003/5.0。<br/>3.&nbsp;&nbsp;用 SP5 SDK编译的话，支持SP5/PPC5。<br/>4.&nbsp;&nbsp;用 PPC 5 编译的话，只支持 PPC5。<br/><br/>基于以下假定，我整理了一个小的CeleMenuBar类，在使用的时候，只要：<br/><br/>1.&nbsp;&nbsp;在资源中定义 IDC_LSK 和 IDC_RSK （=IDC_LSK+1），用于定义左右按钮的命令ID。<br/>2.&nbsp;&nbsp;在资源中添加一个菜单，如果不是Popup按钮，则用 IDC_LSK 或 IDC_RSK作为命令。<br/>3.&nbsp;&nbsp;如果你的代码需要支持 2003，则请在资源中定义 MenuBar 的 RCDATA；如果只需要支持5.0，则不需要。<br/><br/>4. 在代码中，使用 CeleMenuBar，操作所有的MenuBar按钮都不用管命令ID，只需要指明是左按钮还是右按钮。<br/>5. 在代码中，如果需要响应按钮命令，请使用 IDC_LSK 和 IDC_RSK；如果是弹出菜单，无视 。<br/> <br/>基于以上几个规则，代码写起来就简单多了。<br/><br/><div class="code">// CeleMenuBar<br/>#ifndef IDC_LSK<br/>#ifndef TBIF_BYINDEX<br/>#pragma message(&quot;CeleMenuBar: IDC_LSK is not defined. You should use IDOK &amp; IDCANCEL as soft key command.&quot;)<br/>#endif<br/>#define IDC_LSK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IDOK<br/>#define IDC_RSK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IDCANCEL<br/>#endif<br/>#if TBIF_BYINDEX<br/>#define _MBIF(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((x) &#124; TBIF_BYINDEX)<br/>#define _MBID(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(x)<br/>#else<br/>#define _MBIF(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(x)<br/>#define _MBID(x)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(IDC_LSK + (x))<br/>#endif<br/>class CeleMenuBar<br/>&#123;<br/>protected:<br/>&nbsp;&nbsp;&nbsp;&nbsp;HWND m_hMenuBar;<br/><br/>public:<br/>&nbsp;&nbsp;&nbsp;&nbsp;CeleMenuBar(HWND hMenuBar = NULL)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_hMenuBar = hMenuBar;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;operator HWND()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return m_hMenuBar;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;HWND operator =(HWND hMenuBar)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return m_hMenuBar = hMenuBar;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 创建菜单条<br/>&nbsp;&nbsp;&nbsp;&nbsp;HWND Create(HWND hParent, UINT uBarRes = 0, DWORD dwFlags = 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHMENUBARINFO mb = &#123;0&#125;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mb.cbSize = sizeof(SHMENUBARINFO);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mb.hwndParent = hParent;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mb.hInstRes = g_hInst;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mb.nToolBarId = uBarRes;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (uBarRes)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>#ifdef TBIF_BYINDEX<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mb.dwFlags = dwFlags &#124; SHCMBF_HMENU;<br/>#else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mb.dwFlags = dwFlags;<br/>#endif<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mb.dwFlags = SHCMBF_EMPTYBAR;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHCreateMenuBar(&amp;mb);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_Assert(mb.hwndMB);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return m_hMenuBar = mb.hwndMB;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 获取弹出菜单<br/>&nbsp;&nbsp;&nbsp;&nbsp;HMENU GetMenu(BOOL bRight = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>#ifdef TBIF_BYINDEX<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TBBUTTON tb;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.dwData = NULL;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(m_hMenuBar, TB_GETBUTTON, _MBID(bRight), (LPARAM) &amp;tb);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (HMENU) tb.dwData;<br/>#else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (HMENU) SendMessage(m_hMenuBar, SHCMBM_GETSUBMENU, 0, _MBID(bRight));<br/>#endif<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 重载按键<br/>&nbsp;&nbsp;&nbsp;&nbsp;DWORD OverrideKey(WPARAM wParam = VK_TBACK)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SendMessage(m_hMenuBar, SHCMBM_OVERRIDEKEY, wParam, MAKELPARAM(SHMBOF_NODEFAULT &#124; SHMBOF_NOTIFY, SHMBOF_NODEFAULT &#124; SHMBOF_NOTIFY));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 获取按钮文字<br/>&nbsp;&nbsp;&nbsp;&nbsp;BOOL GetButtonText(PTSTR ptzStr, BOOL bRight = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TBBUTTONINFO tb;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.cbSize = sizeof(TBBUTTONINFO);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.dwMask = _MBIF(TBIF_TEXT);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.pszText = ptzStr;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.cchText = MAX_PATH;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SendMessage(m_hMenuBar, TB_GETBUTTONINFO, _MBID(bRight), (LPARAM) &amp;tb);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 设置按钮文字<br/>&nbsp;&nbsp;&nbsp;&nbsp;BOOL SetButtonText(PCTSTR ptzStr, BOOL bRight = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TBBUTTONINFO tb;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.cbSize = sizeof(TBBUTTONINFO);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.dwMask = _MBIF(TBIF_TEXT);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.pszText = (PTSTR) ptzStr;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SendMessage(m_hMenuBar, TB_SETBUTTONINFO, _MBID(bRight), (LPARAM) &amp;tb);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 获取按钮状态<br/>&nbsp;&nbsp;&nbsp;&nbsp;BYTE GetButtonState(BOOL bRight = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TBBUTTONINFO tb;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.cbSize = sizeof(TBBUTTONINFO);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.dwMask = _MBIF(TBIF_STATE);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage(m_hMenuBar, TB_GETBUTTONINFO, _MBID(bRight), (LPARAM) &amp;tb);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return tb.fsState;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 设置按钮状态<br/>&nbsp;&nbsp;&nbsp;&nbsp;BOOL SetButtonState(BYTE bState = TBSTATE_ENABLED, BOOL bRight = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TBBUTTONINFO tb;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.cbSize = sizeof(TBBUTTONINFO);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.dwMask = _MBIF(TBIF_STATE);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tb.fsState = bState;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SendMessage(m_hMenuBar, TB_SETBUTTONINFO, _MBID(bRight), (LPARAM) &amp;tb);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 启用或禁用按钮<br/>&nbsp;&nbsp;&nbsp;&nbsp;BOOL EnableButton(BOOL bEnable = TRUE, BOOL bRight = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SetButtonState(bEnable ? TBSTATE_ENABLED : 0, bRight);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 显示或隐藏按钮<br/>&nbsp;&nbsp;&nbsp;&nbsp;BOOL HideButton(BOOL bHide = TRUE, BOOL bRight = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SetButtonState(bHide ? TBSTATE_HIDDEN : 0, bRight);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 弹出菜单，用于需要动态切换弹出菜单的情况<br/>&nbsp;&nbsp;&nbsp;&nbsp;BOOL PopupMenu(HMENU hMenu, BOOL bRight = TRUE)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BYTE bState = GetButtonState(bRight);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (bState &amp; TBSTATE_PRESSED)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keybd_event(VK_ESCAPE, 0, KEYEVENTF_SILENT, 0);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keybd_event(VK_ESCAPE, 0, KEYEVENTF_SILENT &#124; KEYEVENTF_KEYUP, 0);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RECT rt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetWindowRect(m_hMenuBar, &amp;rt);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetButtonState(bState &#124; TBSTATE_PRESSED, bRight);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TrackPopupMenuEx(hMenu, bRight ? (TPM_RIGHTALIGN &#124; TPM_BOTTOMALIGN) : (TPM_LEFTALIGN &#124; TPM_BOTTOMALIGN), <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bRight ? rt.right : rt.left, rt.top, GetParent(m_hMenuBar), NULL);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SetButtonState(bState &amp; ~TBSTATE_PRESSED, bRight);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&#125;;</div>
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?454</link>
<title><![CDATA[PPC 中打开通话记录]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Thu, 02 Apr 2009 13:41:28 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?454</guid> 
<description>
<![CDATA[ 
	SP 中有一个exe用来打开通话记录，万恶的WM竟然弄得PPC上不一样。经分析找到一个简洁的方法，可以在PPC中打开通话记录界面，代码如下：<br/><br/><div class="code"><br/>if (HWND hWnd = FindWindow(TEXT(&quot;MSCProg&quot;), NULL))<br/>&#123;<br/>&nbsp;&nbsp;PostMessage(hWnd, 0x801A, 0, 0);<br/>&#125;</div><br/><br/><br/><br/>又他妈的是私有的消息，做出这么垃圾的系统垃圾的设计，WM 的设计者真该去S!
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?453</link>
<title><![CDATA[PPC 中向其它进程中插入DLL的方法及通用代码]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Mon, 23 Mar 2009 11:43:29 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?453</guid> 
<description>
<![CDATA[ 
	大家都知道 PC 中写破解补丁的其中一个方法是 Loader，通常的做法是CreateProcess后用CreateRemoteThread来Load我们的DLL。但这个方法在WM中显然不可行（压根没这个API）。<br/><br/>WM中要在指定的进程中执行我们的代码，可以用一个未公开的 <span style="color: #FF0000;">PerformCallBack4</span> API。利用这个API，可以在目标进程中执行我们的代码。<br/><br/>首先声明：这个方法<span style="color: #FF0000;">仅对于SP2003及所有PPC有效，对于SP5及其以上系统非常可能失效</span>，因为SP的权限要求比PPC高。为了在SP5/6中具备同样的功能，需要做一系列非常复杂的操作，我也已经琢磨出相关的方案可通用的代码，说起来比较啰嗦，暂且按下不表，以后再叙吧。<br/><br/><br/>废话不多说，直接看代码：<br/><div class="code">&nbsp;&nbsp;STATIC HMODULE RemoteLoadLibrary(HANDLE hProcess, PCTSTR ptzPath)<br/>&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;BOOL bMode = SetKMode(TRUE);<br/>&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwPerm = SetProcPermissions(0xFFFFFFFF);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;CALLBACKINFO ci;<br/>&nbsp;&nbsp;&nbsp;&nbsp;ci.hProc= hProcess;<br/>&nbsp;&nbsp;&nbsp;&nbsp;ci.pFunc = (FARPROC) MapPtrToProcess(GetProcAddress(GetModuleHandle(TEXT(&quot;COREDLL&quot;)), TEXT(&quot;LoadLibraryW&quot;)), hProcess);;<br/>&nbsp;&nbsp;&nbsp;&nbsp;ci.pvArg0 = MapPtrToProcess((PVOID) ptzPath, GetCurrentProcess());<br/>&nbsp;&nbsp;&nbsp;&nbsp;HMODULE hModule = (HMODULE) PerformCallBack4(&amp;ci, 0, 0, 0);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;SetKMode(bMode);<br/>&nbsp;&nbsp;&nbsp;&nbsp;SetProcPermissions(dwPerm);<br/>&nbsp;&nbsp;&nbsp;&nbsp;return hModule;<br/>&nbsp;&nbsp;&#125;</div><br/><br/>上面的函数中，首先设置权限，然后映射LoadLibraryW的地址到目标进程，然后在目标进程中执行LoadLibraryW装载我们的DLL。OK，既然我们的DLL都被Load到目标进城了，要干什么，请随意（一般来说，DllMain函数中创建一个线程后，立即返回。在线程中做你想做的事）。<br/><br/>使用例子（执行一个目标进程并运行直接运行一个EXE（如果没运行，运行了则直接操作）并运行我们的DLL）：<br/><br/><div class="code">&nbsp;&nbsp;HMODULE hModule = CCodeInj::RemoteLoadLibrary(TEXT(&quot;cprog.exe&quot;), tzDllPath);<br/>&nbsp;&nbsp;if (hModule == NULL)<br/>&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Sleep(500);<br/>&nbsp;&nbsp;&nbsp;&nbsp;PROCESS_INFORMATION pi;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (CreateProcess(TEXT(&quot;cprog.exe&quot;),, NULL, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &amp;pi))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(2000);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hModule = CCodeInj::RemoteLoadLibrary(pi.hProcess, tzDllPath);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(pi.hThread);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(pi.hProcess);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&#125;</div><br/><br/>为了更好地使用，我提供了更多的功能，请参看附件。<br/><br/>下载附件请到：<a href="http://bbs.pediy.com/showthread.php?p=595544#post595544" target="_blank">http://bbs.pediy.com/showthread.php?p=595544#post595544</a><br/>或者来信至 Yonsm@msn.cm<br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content"><br/>1.你得准备一个 DLL，假设是 MyHook.dll<br/>2 另有一个代码执行的空间（无论是EXE还是DLL，也可以在 MyHook.dll），然后在这个代码空间执行：RemoteLoadLibrary<br/>&nbsp;&nbsp; 指定远程进程（比如 cprog.exe，就是你要插入的进程），和DLL路径（就是MyHook.dll的路径）<br/>3. 那么，RemoteLoadLibrary就会让 crpog.exe 来 LoadLibrary(MyHook.dll)，你在MyHook.dll里面就可以做你想做的事。<br/></div></div><br/><br/>
]]>
</description>
</item><item>
<link>HTTP://WWW.Yonsm.NET/read.php?445</link>
<title><![CDATA[MSVC 中的几个非标准特殊关键字]]></title> 
<author>Yonsm &lt;Yonsm@163.com&gt;</author>
<category><![CDATA[文档]]></category>
<pubDate>Wed, 17 Dec 2008 07:43:14 +0000</pubDate> 
<guid>HTTP://WWW.Yonsm.NET/read.php?445</guid> 
<description>
<![CDATA[ 
	MSVC 中的有些非标准的关键字，有些时候特别有用。<br/><br/>1. __if_exist() 和 __if_not_exist()<br/><br/>用途：判断一个变量是否存在，（在编译期）以便选择相应的代码。<br/>举例：以下代码，无论 g_hInst 是否声明，都不会编译出错。<br/><br/>__if_exist (g_hInst)<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoadString(g_hInst, ...)<br/>&#125;<br/>__if_not_exist (g_hInst)<br/>&#123;<br/>&nbsp;&nbsp; LoadString(NULL ...)<br/>&#125;<br/><br/><br/>2.__declspec(selectany)<br/><br/>用途：指明变量或函数实体在连接是只选择其中一个实体拷贝。<br/>举例：在头文件中声明一个变量，即使很多CPP文件包含它，连接期间也只会选择其中一个，从而避免错误。<br/><br/>__declspec(selectany) HINSTANCE g_hInst;<br/><br/>这样就不必在.cpp中定义变量，在.h中声明变量了（直接在.h中定义，多余的副本会被连接器抛弃）。<br/><br/>3.以前介绍过的#pragma、naked等等，参考以前的文档......<br/>
]]>
</description>
</item>
</channel>
</rss>