??xml version="1.0" encoding="utf-8" standalone="yes"?>
“没有扑ֈ MSVCR80D.dll,因此q个E序未能启动Q重新安装应用程序,可能会修复此问题?#8221;
在VS2005中,l常到q个问题Q怎么办呢Q是ȝ上下载一个dll么?我没有尝试过。但是网上提供的一U方法是q样的,我觉得挺便的?br>
如图Q?br>
?Use FAT32 Work-around" 设ؓyes可以了?br>
]]>
书中l了一些徏议和ҎQ?/span>
一是有计划地对付错误?/span>
对应用程序展开适当的调试,应该是远在你使用调试器之前就开始了。多多?/span>ASSERT调试措施。(ASSERT背后的概忉|安全和速度之间的交换。程序运行因此运行得比较慢,但是Debug Build的制造就是ؓ了调试,所以可以理解)在每一个你的假设之处做验工作。进入一个函数时Q确认所有状态。不要只是检查指针是否合法;如果可能Q检查一下指针所指的l构中的数据是否一致?/span>
二是Bench Testing
其实q种Ҏ是先撇开多线E的环境Q测试程序逻辑的正性。如?/span>OK了,然后再考虑与线E相关的东西?/span>
三是U程对话?/span>
q里主要讨论了对一个特定的U程如何调试Q方法是挂v所有的U程——除了我们关注的那个。书中介l的Ҏ?/span>vs 2005我没有找到?/span>
四是日志记录
q里主要是在控制台窗口显CZ些运行信息,我们可以使用printf{函数在控制台输Z些信息来查看U程的运行次序?/span>
五是内存记号
使用内存记号的好处就是降低彼此干扰的可能性。但是也要注意它不是同步操作Q可能会因ؓ两个U程的同时写入引来问题?/span>
六是g调试寄存?/span>
前面的这六种Ҏ我也只用q三U,有一些还真是W一ơ见到。不q不怕下ơ搞不定问题的时候可以拿来进行尝试,来抓一抓隐藏在E序中的“臭虫?#8221;?/span>
成功消除多线E程序的“臭虫”Q作者说需要具备三U素养:军_、耐心、创造力。同时也不要蛮干Q要采用U学的方法:观察、预、测试?/span>
ȝ一下:借助ҎQ观察现象,大胆预测Q勇敢尝试,完备试?/span>
目中也到了多U程的用。未来可能多U程的用会来多Q不能停留在完成功能和Q务上Q应该多思考多试。避免多U程的不可确定性带来的一些困扰?/span>
学习书籍Q?/span>Win32 多线E程序设计》侯捯
可以自行创徏一接入炏V以下代码创Z个CMWAP接入点:
CString strFavoriteXml =
L"<wap-provisioningdoc>"
L"<characteristic type="CM_Networks">"
L"<characteristic type="Test_GPRS">"
L"<parm name="DestId" value="{D1D06580-C364-55ec-9421-6ACF34129C58}" />"
L"</characteristic>"
L"</characteristic>"
L"<characteristic type="CM_GPRSEntries">"
L"<characteristic type="Test_GPRS">"
L"<parm name="DestId" value="{D1D06580-C364-55ec-9421-6ACF34129C58}" />"
L"<characteristic type="DevSpecificCellular">"
L"<parm name="BearerInfoValid" value="1" />"
L"<parm name="GPRSInfoValid" value="1" />"
L"<parm name="GPRSInfoProtocolType" value="2" />"
L"<parm name="GPRSInfoL2ProtocolType" value="PPP" />"
L"<parm name="GPRSInfoAccessPointName" value="cmwap" />"
L"<parm name="GPRSInfoAddress" value="" />"
L"<parm name="GPRSInfoDataCompression" value="1" />"
L"<parm name="GPRSInfoHeaderCompression" value="1" />"
L"<parm name="GPRSInfoParameters" value="" />"
L"</characteristic>"
L"</characteristic>"
L"</characteristic>"
L"<characteristic type="CM_ProxyEntries">"
L"<characteristic type="WAP">"
L"<parm name="SrcId" value="{D1D06580-C364-55ec-9421-6ACF34129C58}" />"
L"<parm name="DestId" value="{436EF144-B4FB-4863-A041-8F905A62C572}" />"
L"<parm name="Proxy" value="10.0.0.172:80" />"
L"<parm name="Enable" value="1" />"
L"<parm name="Type" value="1" />"
L"</characteristic>"
L"</characteristic>"
L"</wap-provisioningdoc>";
LPWSTR pszwXMLout = NULL;
HRESULT hr = DMProcessConfigXML(strFavoriteXml, CFGFLAG_PROCESS, &pszwXMLout);
if ( pszwXMLout )
{
delete [] pszwXMLout;
pszwXMLout = NULL;
}
现在?Windows Mobile 讑֤大多数都拥有电话和其他无UK信的功能。在许多情况下,你想让你的应用程序跟q些通信功能q行交互。例如,你想在电话响L时候,你的应用程序播N乐的声音调小Q或者需要直接对通信gq行各种操作。那么开发这U类型的应用E序往往比较困难Q最大的隄在于试应用E序?br>
Z解决试q种应用E序的困难,Windows Mobile 6 SDK 包含?Cellular EmulatorQ蜂H仿真器Q。Cellular Emulator 让你能够?Device Emulator 中,试你的应用E序在各U蜂H通信的情况下的行为?br>
Cellular Emulator 是一个强大的试工具Q它可以用于试你的应用E序在蜂H通信状况变化时的行ؓ。用 Cellular Emulator 可以执行一些简单的试Q如Q在仿真器中拨打电话Q接听来电和挂断电话Q发送和接收 SMS 信息{。ؓ了让开发h员可以测试更复杂的功能,Cellular Emulator q支持对 SIM 配置信息的修改,q有选择2G|络q是3G|络。所有这些测试工作都不需要用C台物理设备?/p>
要让 Cellular Emulator ?Device Emulator 可以一起配合用,首先你需要把他们兌h?br>1. C Cellular Emulator 左下角状态栏?COM 端口受如 COM5?br>2. ?Device Emulator 中选择“File-->Configure...”菜单,打开 Emulator Properties 对话框?br>3. ?Emulator Properties 对话框中选择 Peripherals 选项卡?br>4. 把刚才记下的 COM 端口可入到 Serial Port 0 文本框中。如果你在下拉列表中找不C的端口号Q可以自p入进厅R?br>5. 点击 OK 按钮保存讄Q关?Emulator Properties 对话框?br>6. 点击“File-->Reset-->Soft”菜单,对仿真器q行软重|操作?br>
待仿真器完成重置q程q新启动后Q你会看到仿真器的蜂窝|络已经可用了。如果还是不行,可能是安装了 Windows Mobile 6 SDK 之后Q没有重新启动系l的原因吧?br>
l仿真器拨打电话
打开 Cellular Emulator ?Call Manager 选项卡,?Phone Number 文本框中输入L一个电话号码,点击旁边?Dial 按钮Q仿真器的电话铃声将响vQƈ昄来自所输入的电话号码的来电。这时在 Active Calls 列表中将出现仿真器上的活动通话Q?strong>Status 昄?Incoming?br>?272024q个电话L向仿真器拨打电话Q?br>
仿真器收到电话号码ؓ7272024的来电:
从仿真器拨打电话
?Preset Number 列表中提供了4个可供测试的电话L?strong>Busy 表示U\忙,Reject 表示拒绝接听Q?strong>Hang Up After Connect 表示接听后再挂断Q?strong>No Answer 表示没有回应。尝试在仿真器中拨打7272021QCellular Emulator ?Active Calls 列表显CZ真器当前的活动通话。电话接通后持箋?0U钟Q然后挂断,也就?strong>Hang Up After Connect?br>
向仿真器发?SMS 信息
打开 Cellular Emulator ?SMS 选项卡,?Send to device 的多行文本框中输入短信内容,然后点击 Send 按钮短信发送至仿真器?br>
仿真器将收到新短信:
q可以设|重复发送。选中 Repeatly 查框Q设定好 IntervalQ间隔时_?Max CountQ最大数目)Q然后再点击 Send 按钮卛_。如果你在仿真器中回复了信息Q将会在 Cellular Emulator ?Receive from device 列表中看C回复的短信?br>
选择|络
打开 Cellular Emulator ?Network 选项卡,可以选择2G或?G|络Q断开 GPRS q接Q查看数据通道{?br>
执行和查?AT 命o
打开 Cellular Emulator ?nbsp;Injection 选项卡,q里可以向仿真器发?AT 命o或事件?br>
打开 Cellular Emulator ?nbsp;AT log 选项卡,可以看到刚才所有对仿真器的操作对应?AT 命o?br>
使用配置文g
q里可以选择使用哪一?SIM 配置文gQ文件内Ҏ XML 格式?br>
ȝ
有了 Cellular Emulator 的配合,Device Emulator 昑־更加强大。现?Windows Mobile 6 开发h员可以用仿真器q行开发和试Q而不需要购买各U真实设备。遗憄是,Cellular Emulator q不支持 Windows Mobile 5.0 ?Windows Mobile 2003 的仿真器。不q好?Windows Mobile 6 ?API ?Windows Mobile 5.0 的绝大部分一P所以你可以?Windows Mobile 6 的仿真器中开发和调试 Windows Mobile 5.0 的应用程序。对?Windows Mobile 2003 可能试效果没有那么一_你也可以自己试一下?br>
参考:
What's New for Developers in Windows Mobile 6
if (SUCCEEDED(SimReadPhonebookEntry(lphSim, SIM_PBSTORAGE_SIM, i+1, &phoneent)))
{
CONTACTSTRUCT tempContact = {0};
wcsncpy(tempContact.szName, phoneent.lpszText, 31); // 姓名
wcsncpy(tempContact.szTelNum, phoneent.lpszAddress, 31); // 电话
vContact.push_back(tempContact );
}
}
//最后别忘了清理
SimDeinitialize(lphSim);
lphSim = NULL;
q里d的时候用了dwTotalQ是因ؓ听有l验的h_sim卡的存储可能不连l,如果用dwUsed的话Q可能会有问题?br>
U篏一下,有时间再好好看一下outlook联系人的?br>
参考文章:
Pocket 中获取SIM卡中联系Z?br>http://blog.csdn.net/xulg1984/archive/2008/05/30/2497712.aspx
转自: http://www.cnblogs.com/dotnetearthworm/archive/2009/02/02/1382488.html
.slnQ解x案文Ӟx案资源管理器提供昄理文g的图形接口所需的信息?
.csproj:目文gQ创建应用程序所需的引用、数据连接、文件夹和文件的信息?
.aspxQWeb H体는两部分组成:视觉元素QHTML、服务器控g和静态文本)和该늚~程逻辑。Visual Studio 这两个l成部分分别存储在一个单独的文g中。视觉元素在.aspx 文g中创建?
.ascxQASP.NET的用hӞ也叫?#8220;pagelets”Q,是作ZU封装了特定功能和行为(q两者要被用在Web应用E序的各U页面上Q的Web面被开发的。一个用h件包含了HTML、代码和其他Web或者用h件的l合Qƈ在Web服务器上以自q文g格式保存Q其扩展名是*.ascx。ASP.NET里的~省配置q不允许Web客户端通过URL来访问这些文Ӟ但是q个|站的其他页面可以集成这些文仉所包含的功能?
.aspx.csQWeb H体늚~程逻辑位于一个单独的cL件中Q该文gUC代码隐藏cLӞ.aspx.csQ?
.csQ?cL块代码文件。业务逻辑处理层的代码?
.asaxQGlobal.asax 文gQ也叫做 ASP.NET 应用E序文gQ是一个可选的文gQ该文g包含响应 ASP.NET ?HTTP 模块引发的应用程序别事件的代码?
.configQWeb.config 文g向它们所在的目录和所有子目录提供配置信息?
.aspx.resx/.resxQ资源文Ӟ资源是在逻辑上由应用E序部v的Q何非可执行数据。通过在资源文件中存储数据Q无需重新~译整个应用E序卛_更改数据?51aspx.com
.XSD:XML schema的一U?从DTD,XDR发展到XSD
.pdb:PDBQ程序数据库Q文件保持着调试和项目状态信息,从而可以对E序的调试配|进行增量链接?
.suo:解决Ҏ用户选项,记录所有将与解x案徏立关联的选项Q以便在每次打开Ӟ它都包含您所做的自定义设|?
.asmxQ?asmx文g包含 WebService 处理指oQƈ用作 XML Web services 的可d入口?51aspx?
.vsdiscoQ项目发玎ͼ文g Z XML 的文Ӟ它包含ؓ Web 服务提供发现信息的资源的链接 (URL-51aspx )?
.htc:一个HTML文g,包含脚本和定义组件的一pdHTC特定元素.htc提供在脚本中implementlg的机?/p>
来源Q?.Net中文CQ?a >http://www.aspxcs.net/)
上面是我看到的一些介l?q里再补充一?
.clw 支持ClassWizard
.ncb 支持ClassView
.opt 保存工作I间的配|?nbsp;
.aps 支持ResourceView
.bsc 览器信息文?nbsp;
.dsp 目文g
.dsw 工作I间文g
.mak 外部的创建文?nbsp;
.plg 建立日志文g
Let's analyze what a title like Learn Pascal in Three Days could mean:
Learn: In 3 days you won't have time to write several significant programs, and learn from your successes and failures with them. You won't have time to work with an experienced programmer and understand what it is like to live in that environment. In short, you won't have time to learn much. So they can only be talking about a superficial familiarity, not a deep understanding. As Alexander Pope said, a little learning is a dangerous thing.
Pascal: In 3 days you might be able to learn the syntax of Pascal (if you already knew a similar language), but you couldn't learn much about how to use the syntax. In short, if you were, say, a Basic programmer, you could learn to write programs in the style of Basic using Pascal syntax, but you couldn't learn what Pascal is actually good (and bad) for. So what's the point? Alan Perlis once said: "A language that doesn't affect the way you think about programming, is not worth knowing". One possible point is that you have to learn a tiny bit of Pascal (or more likely, something like Visual Basic or javascript) because you need to interface with an existing tool to accomplish a specific task. But then you're not learning how to program; you're learning to accomplish that task.
in Three Days: Unfortunately, this is not enough, as the next section shows.
Teach Yourself Programming in Ten Years
Researchers (Hayes, Bloom) have shown it takes about ten years to develop expertise in any of a wide variety of areas, including chess playing, music composition, painting, piano playing, swimming, tennis, and research in neuropsychology and topology. There appear to be no real shortcuts: even Mozart, who was a musical prodigy at age 4, took 13 more years before he began to produce world-class music. In another genre, the Beatles seemed to burst onto the scene, appearing on the Ed Sullivan show in 1964. But they had been playing since 1957, and while they had mass appeal early on, their first great critical success, Sgt. Peppers, was released in 1967. Samuel Johnson thought it took longer than ten years: "Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price." And Chaucer complained "the lyf so short, the craft so long to lerne."
Here's my recipe for programming success:
Get interested in programming, and do some because it is fun. Make sure that it keeps being enough fun so that you will be willing to put in ten years.
Talk to other programmers; read other programs. This is more important than any book or training course.
Program. The best kind of learning is learning by doing. To put it more technically, "the maximal level of performance for individuals in a given domain is not attained automatically as a function of extended experience, but the level of performance can be increased even by highly experienced individuals as a result of deliberate efforts to improve." (p. 366) and "the most effective learning requires a well-defined task with an appropriate difficulty level for the particular individual, informative feedback, and opportunities for repetition and corrections of errors." (p. 20-21) The book Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life is an interesting reference for this viewpoint.
If you want, put in four years at a college (or more at a graduate school). This will give you access to some jobs that require credentials, and it will give you a deeper understanding of the field, but if you don't enjoy school, you can (with some dedication) get similar experience on the job. In any case, book learning alone won't be enough. "Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter" says Eric Raymond, author of The New Hacker's Dictionary. One of the best programmers I ever hired had only a High School degree; he's produced a lot of great software, has his own news group, and through stock options is no doubt much richer than I'll ever be.
Work on projects with other programmers. Be the best programmer on some projects; be the worst on some others. When you're the best, you get to test your abilities to lead a project, and to inspire others with your vision. When you're the worst, you learn what the masters do, and you learn what they don't like to do (because they make you do it for them).
Work on projects after other programmers. Be involved in understanding a program written by someone else. See what it takes to understand and fix it when the original programmers are not around. Think about how to design your programs to make it easier for those who will maintain it after you.
Learn at least a half dozen programming languages. Include one language that supports class abstractions (like Java or C++), one that supports functional abstraction (like Lisp or ML), one that supports syntactic abstraction (like Lisp), one that supports declarative specifications (like Prolog or C++ templates), one that supports coroutines (like Icon or Scheme), and one that supports parallelism (like Sisal).
Remember that there is a "computer" in "computer science". Know how long it takes your computer to execute an instruction, fetch a word from memory (with and without a cache miss), read consecutive words from disk, and seek to a new location on disk. (Answers here.)
Get involved in a language standardization effort. It could be the ANSI C++ committee, or it could be deciding if your local coding style will have 2 or 4 space indentation levels. Either way, you learn about what other people like in a language, how deeply they feel so, and perhaps even a little about why they feel so.
Have the good sense to get off the language standardization effort as quickly as possible.
With all that in mind, its questionable how far you can get just by book learning. Before my first child was born, I read all the How To books, and still felt like a clueless novice. 30 Months later, when my second child was due, did I go back to the books for a refresher? No. Instead, I relied on my personal experience, which turned out to be far more useful and reassuring to me than the thousands of pages written by experts.
Fred Brooks, in his essay No Silver Bullets identified a three-part plan for finding great software designers:
Systematically identify top designers as early as possible.
Assign a career mentor to be responsible for the development of the prospect and carefully keep a career file.
Provide opportunities for growing designers to interact and stimulate each other.
This assumes that some people already have the qualities necessary for being a great designer; the job is to properly coax them along. Alan Perlis put it more succinctly: "Everyone can be taught to sculpt: Michelangelo would have had to be taught how not to. So it is with the great programmers".
So go ahead and buy that Java book; you'll probably get some use out of it. But you won't change your life, or your real overall expertise as a programmer in 24 hours, days, or even months.
References
Bloom, Benjamin (ed.) Developing Talent in Young People, Ballantine, 1985.
Brooks, Fred, No Silver Bullets, IEEE Computer, vol. 20, no. 4, 1987, p. 10-19.
Hayes, John R., Complete Problem Solver Lawrence Erlbaum, 1989.
Lave, Jean, Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life, Cambridge University Press, 1988.
http://www.norvig.com/
?/span>Windows Mobile 5.0SDK?/span>HelloSMS例子中,发送短信的代码是这样写?/span>
q段代码在一般情况下是运行正的Q对于手Z手机的发送是不存在问题的Q但是与SP的交互在某些省区存在短信发送不出去的情c?span lang=EN-US>
Z更好的理解这D代码,我们先来熟悉一?span lang=EN-US style="COLOR: black">SmsSendMessage及各个参数?span lang=EN-US>
SmsSendMessage
功能Q?/span>Use the SmsSendMessage function to create and send an Short Message Service (SMS) message.Q创建和发送短信,但短信发送后q不保存到发件箱中)
原型Q?span lang=EN-US>
HRESULT SmsSendMessage (
const SMS_HANDLE smshHandle, // 调用SmsOpen时获得的短信句柄
const SMS_ADDRESS * const psmsaSMSCAddress, //指向短信中心L的地址
const SMS_ADDRESS * const psmsaDestinationAddress, // 发送的目的地址
const SYSTEMTIME * const pstValidityPeriod, // 发送时间的有效?span lang=EN-US>
const BYTE * const pbData, // 信息的内定w?span lang=EN-US>
const DWORD dwDataSize,// 信息内容的长?span lang=EN-US>
const BYTE * const pbProviderSpecificData, //q营商的附加数据
const DWORD dwProviderSpecificDataSize, // 附加数据的长?span lang=EN-US>
const SMS_DATA_ENCODING smsdeDataEncoding, // 短信~码
const DWORD dwOptions, // 其他选项
SMS_MESSAGE_ID * psmsmidMessageID); // 用于得到pȝ回执的信?span lang=EN-US>
Q具体介l可查看http://msdn.microsoft.com/en-us/library/aa455068.aspxQ?span lang=EN-US>
在实际应用中短信发送不出去Q但?span lang=EN-US>SmsSendMessage的返回值是S_OK倹{在一些文章中有hq样认ؓ是短信编码的问题造成的?span lang=EN-US>
如果~码格式不对可能造成短信中心|关把短信给吞掉的情况,E序虽然调用成功Q但是就是目标号码收不到短信。函数参C的后三个参数可以不用或设默认值都可以?span lang=EN-US>
起初我也是认个地斚w成的,很是兴奋。短信的回复内容Cؓ字母Q我误以为短信内Ҏ时是7-BIT的短消息Q短信网x短信l吞掉了Q造成目标L收不到短信。在l习中却也阴差阳错的成功了。很高兴的把理由归到了这个地斏Vƈq样ȝQ?/span>SmsSendMessage可以支持7-bit?span lang=EN-US>ASCII码的短消息,也支?span lang=EN-US>16-bit?span lang=EN-US>unicode的短消息。但内容?span lang=EN-US>ASCII的时候,短信~码?span lang=EN-US style="COLOR: black"> SMSDE_GSM?span lang=EN-US>SMSDE_OPTIMALQ当内容不全?/span>ASCII的时候,短信~码?span lang=EN-US style="COLOR: black">SMSDE_GSM?span lang=EN-US>SMSDE_OPTIMAL。所以回复内Ҏ为汉字即可?span lang=EN-US>
但是q样对么Qv初我认ؓ我的解释很合?span lang=EN-US>.但是我却发现我的一个参C原来的程序不一?span lang=EN-US>.
是我在尝试中无意修改了一个参?span lang=EN-US>,?span lang=EN-US>
tpsd.psMessageClass = PS_MESSAGE_CLASS1;
修改Z
tpsd.psMessageClass = PS_MESSAGE_CLASSUNSPECIFIED;
q是发送短信中的运营商的指定数?/span>TEXT_PROVIDER_SPECIFIC_DATA,它的参数psMessageClass是指
Text Short Message Service (SMS) messages with the appropriate flag can replace previously received notifications with a similar flag and originating address.
它有以下五个?/span>:
PS_MESSAGE_CLASS0: The message should be displayed immediately but not stored. The MS shall send an acknowledgement to the service center when the message has successfully reached the MS. Q被接受后立xCZ不存?/span>(UCؓ闪信)。需要向SMSC发送确认信息。)
PS_MESSAGE_CLASS1Q?/span>The message should be stored and an acknowledgement should be sent to the
PS_MESSAGE_CLASS2Q?/span>The message should be transferred to the SMS data field in the subscriber identity module (SIM) before an acknowledgement is sent to the
PS_MESSAGE_CLASS3Q?/span>When the message has successfully reached the destination and can be stored, an acknowledgement is sent to the
PS_MESSAGE_CLASSUNSPECIFIEDQ?/span>The message Class is not set in the outgoing or incoming message. Q对发出或收到的短信不进行设|)
分析以上五个|前四个值有一个共同的特点Q都需要向SMSC发送确认。而最后一个值没有设定?/span>
q个值的改动Q解决了我所遇到的问题。但I其原因,我有些想不通ؓ什?
但是在实际应用中Q出Ctmail.exe的异常。不知道是这个值的变动带来的问题,q是实际模块中存在的问题。还需要l研I一下?br>
如果大家有知道的,l些?
Hibernate
This is the amount of memory the shell tries to keep free at all times. If the amount of free memory falls below this value then the low memory check routine will try to free up memory. It will do this by first sending WM_HIBERNATE to all valid applications. When an application receives this message it should try to free as many resources as possible. When the low memory check routine runs again and the amount of free memory is still below the hibernate level then the shell will try to close the least recently used (LRU) application by sending a WM_CLOSE message. If the low memory check routine runs yet again and the amount of free memory is still below the hibernate level then the shell will call TerminateProcess on the LRU application that it last sent the WM_CLOSE message to.
我对q段话的理解是:当空闲内存小于HibernateӞpȝ便会试释放内存。首先他会向所有有效的E序发送WM_HIBERNATE。应用程序收到该消息后,会尽量释放资源来释放内存。如果还低于q个值的话,发送WM_CLOSE消息l最q很用的E序。如果还低于该值的Q就关闭该程序了?br>
q个Ҏg有效Q但是用户再hE序的话Q还是一L效果Qƈ不是辑ֈ了什么释攑ֆ存的效果。如何记录最q很用的E序Q这个是不是有什么方法获得呢Q?br>
可以像pȝ提示的那P内存不Q请释放一些内存。手工做一些比较好?br>
也看了一些相q的E序的做法,g效果也没有大家说的那么好?br>
?a target=_blank>How the Windows Mobile 5.0 Shell Handles Low Memory Situations的最后,q样写的
What can my Application do?
The best thing your application can do when faced with a low memory situation is to play nicely with the rest of the device.
1、If your application receives a WM_HIBERNATE message free up any resources not absolutely required.
2、If you are planning on allocating a large amount of memory (or if a large allocation fails) you should call SHCloseApps, which will invoke the shell low memory check routine and will try to ensure that enough free memory exists. See below for an example:
例子Q?br>
q个是书中的例子的代码,我只是将它归lؓ了一个函数ErrorShow。这h们在一个函数的后面调用Q直接可以知道错误的原因。不q环境我是在smart device 的DEBUG环境下调时的QOutputDebugString会输出相应的字符丌Ӏ?br>
q个例子中同时展CZFormatMessage的两U用法。观察一下第二个参数明白了?br>
visual studio 也提供了一个查询错误的工P为Error Lookup。通过以上的示例,我们q道其相应的工作原理呢?br>
q本书的源码的下载地址Q?a >http://wintellect.com/Books.aspx
大家如果对windows ~程感兴的话,不妨下来看看?br>
// 选择文g CFileDialog fileDlg(TRUE, "*.txt", "*.txt", NULL, "文本文g (*.txt)|*.txt||", this); fileDlg.m_ofn.Flags |= OFN_FILEMUSTEXIST; fileDlg.m_ofn.lpstrTitle = "通过内存映射文gd数据"; if (fileDlg.DoModal() == IDOK) { // 创徏文g对象 HANDLE hFile = CreateFile(fileDlg.GetPathName(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { TRACE("创徏文g对象p|,错误代码:%d\r\n", GetLastError()); return; } // 创徏文g映射对象 HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); if (hFileMap == NULL) { TRACE("创徏文g映射对象p|,错误代码:%d\r\n", GetLastError()); return; } // 得到pȝ分配_度 SYSTEM_INFO SysInfo; GetSystemInfo(&SysInfo); DWORD dwGran = SysInfo.dwAllocationGranularity; // 得到文g寸 DWORD dwFileSizeHigh; __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh); qwFileSize |= (((__int64)dwFileSizeHigh) << 32); // 关闭文g对象 CloseHandle(hFile); // 偏移地址 __int64 qwFileOffset = 0; // 块大?br> DWORD dwBlockBytes = 1000 * dwGran; if (qwFileSize < 1000 * dwGran) dwBlockBytes = (DWORD)qwFileSize; while (qwFileOffset > 0) { // 映射视图 LPBYTE lpbMapAddress = (LPBYTE)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS, (DWORD)(qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF), dwBlockBytes); if (lpbMapAddress == NULL) { TRACE("映射文g映射p|,错误代码:%d\r\n", GetLastError()); return; } // Ҏ的视图q行讉K for(DWORD i = 0; i < dwBlockBytes; i++) BYTE temp = *(lpbMapAddress + i); // 撤消文g映像 UnmapViewOfFile(lpbMapAddress); // 修正参数 qwFileOffset += dwBlockBytes; qwFileSize -= dwBlockBytes; } // 关闭文g映射对象句柄 CloseHandle(hFileMap); AfxMessageBox("成功完成Ҏ件的讉K"); } |
Z护属?/td> | 说明 |
SEC_COMMIT | 为区中的所有页面在内存中或盘面文g中分配物理存储器 |
SEC_IMAGE | 告知pȝQ映的文g是一个可UL的EXE文g映像 |
SEC_NOCACHE | 告知pȝQ未文件的M内存映射文g攑օ高速缓存,多供g讑֤驱动E序开发h员?/td> |
SEC_RESERVE | 对一个区的所有页面进行保留而不分配物理存储?/td> |
BOOL WriteFile(
HANDLE hFile, // 文g句柄
LPCVOID lpBuffer, // 包含写向文g的数?/span>
DWORD nNumberOfBytesToWrite, // 数据包含的字W串的个?/span>
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
W一ơ我写的E序很简?/span>
BOOL WriteOwnFile(TCHAR* pFileName, TCHAR* pBuffer, DWORD dwLen)
{
HANDLE hFile = CreateFile(pFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
Q;
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dwSize = 0;
WriteFile(hFile, pBuffer, dwLen, &dwSize, NULL );
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}
q样是完成了Q但是写出来的文件是q。所以没有进行字W的转换Q我们需要将pBufferq行转换。这p用到?span>WideCharToMultiByte.如何用呢Q?/span>
首先我的Ҏ比较W,我是q么用的Q?/span>
char* pchBuffer = new char[dwLen+1];
WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, pchBuffer, dwLen+1, NULL, FALSE );
WriteFile(hFile, pBuffer, dwLen+1, &dwSize, NULL );
Delete[] pchBuffer;
此时注意Q我?span>WriteFile中用?span>dwLen+1。结果就是在文g的末ևCqQ正好多一个ؕ码出来。所?span>WriteFile?span>nNumberOfBytesToWrite是写的字W串的数目,是不包括’\
q个ҎW,是因为我们的函数可以~减Z个参数。是因ؓ如下q么写时Q?span>dwLen是所要{换的字符串的个数Q此时{换的字符串是包括’\
DWORD dwLen = WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, NULL, NULL, NULL, FALSE );
所以我们再来看一下改写以后的代码
BOOL WriteOwnFile(TCHAR* pFileName, TCHAR* pBuffer)
{
HANDLE hFile = CreateFile(pFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
Q;
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dwSize = 0;
DWORD dwLen = WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, NULL, NULL, NULL, FALSE );
char* pchBuffer = new char[dwLen];
WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, pchBuffer, dwLen, NULL, FALSE );
WriteFile(hFile, pBuffer, dwLen+1, &dwSize, NULL );
delete[] pchBuffer;
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}
q样感觉代码好看多了?/span>
对于W二个问题,文g打开的时候文件创建失败,q没有想好办法解冟뀂我在想是不是我的某些认知存在问题,文g打开的时候,是否可以?/span>CreateFile来打开呢?
HWND hwnd,
SHCHANGENOTIFYENTRY * pshcne
);
其中,hwnd,为接?/span>change notification的窗?/span>;
pshcne是一个指?/span>SHCHANGENOTIFYENTRYl构的指?/span>,它用来指明窗口接收的change notification的类?/span>.如果设ؓNULL,H口接?/span>all file system, network ?/span> mediacd?/span>notifications.
SHCHANGENOTIFYENTRY是什么样的一个结?/span>,我们看一下它的定?/span>
typedef struct tagSHCHANGENOTIFYENTRY {
DWORD dwEventMask;
LPTSTR pszWatchDir;
BOOL fRecursive;
} SHCHANGENOTIFYENTRY;
dwEventMask 指定发生什么时间来发?/span>notification 消息
pszWatchDir 指定监控路径Q该gؓNULL的情况下Q是监控所有的文g?/span>
fRecursive指定是否只监控指定\径还是监控指定\径及其子文g夏V?/span>
知道了这些,我们不妨写一个这L函数Q来启动文g监控?/span>
代码如下Q?/span>
BOOL StartFileMonitor(HWND hWnd, LPTSTR lpFilePath)
{
SHCHANGENOTIFYENTRY schneNotifyEntry;
schneNotifyEntry.dwEventMask = SHCNE_ALLEVENTS;
schneNotifyEntry.pszWatchDir = lpFilePath;
schneNotifyEntry.fRecursive = TRUE;
return SHChangeNotifyRegister(hWnd, &schneNotifyEntry);
}
2、如何处?/span>WM_FILECHANGEINFO消息
WM_FILECHANGEINFO 中的参数lParamQ指?/span>FILECHANGENOTIFYQ含有相关的数据。所以我们在收到该消息后Q先作的一部操作就?/span>
FILECHANGENOTIFY *lpfcn = (FILECHANGENOTIFY*)lParam;
FILECHANGENOTIFY的结构ؓQ?/span>
typedef struct tagFILECHANGENOTIFY {
DWORD dwRefCount;
FILECHANGEINFO fci;
} FILECHANGENOTIFY;
我们主要用到了其中的fci参数?/span>
FILECHANGEINFO的结构ؓQ?/span>
struct _FILECHANGEINFO {
DWORD cbSize;
LONG wEventId;
ULONG uFlags;
DWORD dwItem1;
DWORD dwItem2;
DWORD dwAttributes;
FILETIME ftModified;
ULONG nFileSize;
} FILECHANGEINFO, *LPFILECHANGEINFO;
dwEventId ?/span>SHCHANGENOTIFYENTRYl构中的dwEventMask对应?/span>
dwItem1,dwItem2是事件依赖的|里面包括了我们需要的文g的完整\径。如果是q行创徏文g的操作,?/span>dwItem1是创建后文g的完整\径,如果是对文gq行重新命名操作的话Q则dwItem2是修改后文g的完整\径。此处对其他参数不做介绍Q大安要的话,可以查看一下?/span>
我们做完相应的操作后Q要知道释放Q此时要用到SHChangeNotifyFree。这个用hq单很多,?/span>SHChangeNotifyFreeQ?/span>lpfcnQ?/span>
下面l大家一段CZ代码Q如?/span>
case WM_FILECHANGEINFO:
{
FILECHANGENOTIFY *lpfcn;
FILECHANGEINFO *lpfci;
lpfcn = (FILECHANGENOTIFY *)lParam;
if (NULL == lpfcn)
{
break;
}
// see if the pointer to the file change info structure
lpfci = &(lpfcn->fci);
if (NULL == lpfci)
{
break;
}
else
{
switch (lpfci->wEventId)
{
case SHCNE_RENAME:
{
//……
}
break;
}
}
SHChangeNotifyFree(lpfcn);
}
break;
3、如何停止文件监?/span>
停止文g监控比较单,只要使该H口不接?/span>WM_FILECHANGEINFO消息卛_。?/span>SHChangeNotifyDeregister(hWnd)卛_?/span>
以上是我今天学习的一些ȝQ此外需要注意的一个小地方Q在mobile上,把一个文件从一个文件夹拷到另一个文件夹Q此时响应的事g?/span>SHCNE_CREATEQ二从电脑上拯一个文件到mobile上,响应的消息ؓSHCNE_RENAME。我注意C电脑上拷贝的话,mobile会先生成一?/span>Temp文g夹内生成一个时文Ӟ然后再在我们指定的文件夹内生成一个文件。这个机制我q不是很清楚Z么?/span>
error C3861: 'CeMountDBVolEx': identifier not found
error C3861: 'CeMountDBVolEx': identifier not found
error C3861: 'CeCreateDatabaseWithProp
error C3861: 'CeCreateSession': identifier not found
error C3861: 'CeOpenDatabaseInSession': identifier not found
我在.cpp文g的开头加入了
#define EDB
#include <windows.h>
#include <windbase.h>
但是错误q依然存?/p>
从网上搜索了一些方?/p>
在博文《mobile数据库遇到的问题?/font>
http://blog.sina.com.cn/s/blog_4c5ad0740100cvxg.html
它里面徏议?/p>
extern "C"
{
}
但是使用后,问题变成了lnk的错?/p>
error LNK2019: unresolved external symbol
有h在论坛里
#include Windbase_edb.h
也是同样的问?/p>
最后,我问了一下我的同?/p>
他徏议我?/p>
stdafx.h 头文件中d
#define EDB
#include <windows.h>
#include <windbase.h>
q样的确解决了问题?/p>
q程?a onclick="javascript:tagshow(event, '%E9%80%9A%E4%BF%A1');" href="javascript:;" target=_self>通信有以下方?br>Using named objects
Waiting for multiple objects
Waiting in a message loop
Using mutex objects
Using semaphore objects
Using event objects
Using critical section objects
Using timer queues
Using waitable timer objects
q程间的通讯实现QIPCQ的11U方?/span>
q程通常被定义ؓ一个正在运行的E序的实例,它由两个部分l成Q?br>一个是操作pȝ用来理q程?a onclick="javascript:tagshow(event, '%E5%86%85%E6%A0%B8');" href="javascript:;" target=_self>内核对象。内核对象也是系l用来存攑օ于进E的l计信息的地?br> 另一个是地址I间Q它包含所有的可执行模块或DLL模块的代码和数据。它q包含动态分配的I间。如U程堆栈和堆分配I间。每个进E被赋予它自q虚拟地址I间Q当q程中的一个线E正在运行时Q该U程可以讉K只属于它的进E的内存。属于其它进E的内存则是隐藏的,q不能被正在q行的线E访问?br> Z能在两个q程之间q行通讯Q由以下几种Ҏ可供参考:
?6位时代常使用的方式,CWnd中提供支?br>1。窗口消?标准的Windows消息以及专用的WM_COPYDATA消息 SENDMESSAGE()接收端必L一个窗?/p>
2。用共享内存方式(Shared Memory)
a.讑֮一块共享内存区?nbsp;
HANDLE CreateFileMapping(HANDLE,LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR)
产生一个file-mapping核心对象
LPVOID MapViewOfFile(
HANDLE hFileMappingObject,
DWORD dwDesiredAcess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap
);
得到׃n内存?a onclick="javascript:tagshow(event, '%E6%8C%87%E9%92%88');" href="javascript:;" target=_self>指针
b.扑և׃n内存
军_q块内存要以点对点(peer to peer)的Ş式呈?br>每个q程都必L相同的能力,产生׃n内存q将它初始化。每个进E?br>都应该调用CreateFileMapping(),然后调用GetLastError().如果传回的错误代码是ERROR_ALREADY_EXISTS,那么q程可以假设这一׃n内存? 域已l被别的q程打开q初始化了,否则该进E就可以合理的认?排在W一位,q接下来共享内存初始化。还是要使用client/server架构中只有serverq程才应该生ƈ初始化共享内存。所有的q程都应该?br>HANDLE OpenFileMapping(DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName);
再调用MapViewOfFile(),取得׃n内存的指?br> c.同步处理(Mutex)
d.清理(Cleaning up) BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);
CloseHandle()
3。动态数据交换(DDEQ通过l护全局分配内存使的应用E序间传递成为可?br> 其方式是再一块全局内存中手工放|大量的数据Q然后用窗口消息传递内?nbsp; 指针.q是16位WIN时代使用的方式,因ؓ在WIN32下已l没有全局和局部内?nbsp; 了,现在的内存只有一U就是虚存?nbsp;
4。消息管?Message Pipe)
用于讄应用E序间的一条永久通讯通道Q通过该通道可以象自q应用E序
讉K一个^?a onclick="javascript:tagshow(event, '%E6%96%87%E4%BB%B6');" href="javascript:;" target=_self>文g一栯写数据?br> 名管?Anonymous Pipes)
单向动Qƈ且只能够在同一电脑上的各个q程之间动?br> 命名道(Named Pipes)
双向Q跨|络QQ何进E都可以L的抓住,放进道的数据有固定的格式,而用ReadFile()只能d该大的倍数。可以被使用于I/O Completion Ports
5邮g?Mailslots)
q播式通信,?2pȝ中提供的新方法,可以在不同主机间交换数据Q在 WIN9X下只支持邮g槽客?/p>
6Windows套接?Windows Socket)
它具备消息管道所有的功能Q但遵守一套通信标准使的不同操作pȝ之上的应 用程序之间可以互盔R信?/p>
7Internet通信 它让应用E序从Internet地址上蝲?a onclick="javascript:tagshow(event, '%E4%B8%8B%E8%BD%BD');" href="javascript:;" target=_self>下蝲文g
8。RPCQ远E过E调用,很少使用Q因其与UNIX的RPC不兼宏V?/p>
9。串?q行通信(Serial/Parallel Communication)
它允许应用程序通过串行或ƈ行端口与其他的应用程序通信
10。COM/DCOM
通过COMpȝ的代理存Ҏ式进行进E间数据交换Q但只能够表现在Ҏ?nbsp; 函数的调用时传送数据,通过DCOM可以在不同主机间传送数据?/p>
B 中的代码?br>
q是最q看的一片短文的titleQ当时就很好奇?br>l常查阅MSDN的程序员都会有这个印象,微Ycode sample中常见的是ZeroMemoryQ而不是语a提供?#8220;{0}”清零功能Q不q,我一直也没有问个whyQ。c++语法中声明对数组或纯l构QstructQ,可以使用例如SPerson sTest = {0}; 来将所有成员置0.
那篇文章的解释是QMicrosoft使用ZeroMemory会更clearQ因?#8220;= {0}” q样的语法有些生僻,不是所有h都可以一下子明白?/p>
实际上,两者还是有一些区别?br>其一QZeroMemory会将l构所有字节置0Q?{0}只会成员置0Q其中padding字节不变?/p>
其二Q但一个struct有构造函数或虚函数时QZeroMemory可以Q?{0}会编译不q。显Ӟ后者vC一些保护作用,因ؓ对一个有虚函数的对象使用ZeroMemoryӞ会将其虚函数的指针置0Q这是非常危险的Q因用虚函数ӞE序昄会crash。参看如下代码: