这个的确还是挺头疼的。前一阶段同学告诉我,很不幸,今天又给忘了。
查了一下,再根据模糊记忆,还是把方框打上了对勾。
可能你也有这样的烦恼,不妨我们来看一下:
在word字体中选择Wingdings2,然后写一个大写R,这样你就看到方框打对勾了。
好记性真不如烂笔头,占此一角,记录一下。
posted @
2009-03-31 15:44 Sandy 阅读(5390) |
评论 (7) |
编辑 收藏
Windows mobile 中 outlook 中任务,约会,联系人,在调用时,有相应的database oid
对应的database oid 不是很清楚,我通过实验,发现,任务是13, 约会是9, 联系人是10.
那有没有专门的数值对应呢?查了一下,发现这么个东东:
typedef /* [v1_enum] */
enum OlDefaultFolders
{ olFolderCalendar = 9,
olFolderContacts = 10,
olFolderTasks = 13,
olFolderCities = 101,
olFolderInfrared = 102,
} OlDefaultFolders;
和我们的实验数据一样.
不错吧.
posted @
2009-03-30 16:32 Sandy 阅读(206) |
评论 (0) |
编辑 收藏
最近在搞一个小东东,
里面涉及到了DATE和SYSTEMTIME的转换,没有用到过,记录一下.
DATE 转换成SYSTEMTIME VariantTimeToSystemTime
其原型为:
INT VariantTimeToSystemTime(
double vtime, LPSYSTEMTIME lpSystemTime ); SYSTEMTIME转换成DATE
SystemTimeToVariantTime
其原型为:
INT SystemTimeToVariantTime(
LPSYSTEMTIME lpSystemTime,
double *pvtime );
posted @
2009-03-26 09:21 Sandy 阅读(1668) |
评论 (0) |
编辑 收藏
今天调试安装文件的对话框,横屏的时候,Edit框的显示,总会随着滚动条往上移动,下面显示出一大片的空白。
很是郁闷啊……
在代码中修改了很长时间,找不出原因,最后和别人代码比对的时候,发现我竟然是在资源文件中的对话框属性定义中比别人多一个WS_BORDER属性,问题迎刃而解。
但究其原因,还不是很清楚。
WS_BORDER: Create a window that has a border.
似乎也看不出来什么原因。
posted @
2009-03-18 19:00 Sandy 阅读(196) |
评论 (2) |
编辑 收藏
在Windows Mobile中,Edit控件在具有WS_VSCROLL的时候,无论显示文字的多少,都会显示滚动条。如何在显示文字不到一页的情况下,让滚动条不显示呢?
我是这样考虑的:判断显示文字的高度,即显示文字的行数*单个文字的高度,判断其是否大于屏幕高度,如果大于,则改变Edit控件的属性,使其具有WS_VSCROLL属性;如果小于或等于,则改变Edit控件的属性,使其不具有WS_VSCROLL属性。
代码示例:
int height = GetSystemMetrics(SM_CYFULLSCREEN); // 此处示屏幕高度,可自己设定
HWND hEdit = GetDlgItem(hDlg, IDC_EDIT);
DWORD dwLineCount = (DWORD)::SendMessage(hEdit, EM_GETLINECOUNT, 0, 0L);
HDC hdc = GetDC(hDlg);
TEXTMETRIC metric;
GetTextMetrics(hdc, &metric);
ReleaseDC(hDlg, hdc);
if (metric.tmHeight * dwLineCount <= height))
{
SetWindowLong(hEdit, GWL_STYLE, WS_VISIBLE | ES_MULTILINE | ES_READONLY);
}
else
{
SetWindowLong(hEdit,GWL_STYLE, WS_VISIBLE| WS_VSCROLL| ES_MULTILINE |ES_READONLY);
}
我在创建Edit控件的时候,一开始没有设置WS_VSCROLL属性,发现加上WS_VSCROLL属性后,对于按键的上下响应有些问题。后来就反其道而行之,先让其具有WS_VSCROLL属性,然后再判断其是否该显示滚动条。
在Windows Mobile中涉及到横竖屏切换的问题,比如说,在竖屏的时候没有滚动条,到横屏的时候又需要有滚动条,此时怎么办?
在WM_SIZE中进行以上的属性判断,但是有一个问题需要注意:如果需要调整Edit控件的大小,需要在属性判断置后进行。
一点心得,大家可以试试哈!
posted @
2009-03-18 18:48 Sandy 阅读(781) |
评论 (0) |
编辑 收藏
Why is everyone in such a rush?
Walk into any bookstore, and you'll see how to Teach Yourself Java in 7 Days alongside endless variations offering to teach Visual Basic, Windows, the Internet, and so on in a few days or hours. I did the following power search at Amazon.com:
pubdate: after 1992 and title: days and
(title: learn or title: teach yourself)
and got back 248 hits. The first 78 were computer books (number 79 was Learn Bengali in 30 days). I replaced "days" with "hours" and got remarkably similar results: 253 more books, with 77 computer books followed by Teach Yourself Grammar and Style in 24 Hours at number 78. Out of the top 200 total, 96% were computer books.
The conclusion is that either people are in a big rush to learn about computers, or that computers are somehow fabulously easier to learn than anything else. There are no books on how to learn Beethoven, or Quantum Physics, or even Dog Grooming in a few days.
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/
posted @
2009-03-14 10:24 Sandy 阅读(349) |
评论 (0) |
编辑 收藏
昨天才开始认真读《小P成长记》,发现真的很好看。
学习这么久,才发现思考方法的转变还是很重要的。我们往往缺少一位向老C一样的好老师,能够慢慢引导我们学习。
机会难得,我们与小P一样快快成长吧。
读到第一桶第九碗了,
对里面的一些思想和方法很赞同,转过来:
思想:1. 以数据为中心思考问题的解决之道。2. 将对同类数据的操作放在相同的编译单元中。3. 信息隐藏,而不是暴露,以将问题的规模控制在可理解的范围。方法:1. 首先关注整体,而不是细节。2. 先考虑测试,更先于编码。3. 先用伪代码编程,以体现程序的意图,再用具体代码完善之。4. 迅速构建可编译通过的,并且可执行的框架程序,使用测试代码测试之。5. 将以上方法反复应用于子模块,直到问题被解决。6. 在上下文环境中提取对其他模块的需求。7. 先写.h文件,后写.c文件。8. 先快速实现一个可行的解法,再根据反馈信息优化之。
如果大家也关心小P,就一同到那看看,链接地址:
http://www.cppblog.com/enderson/archive/2009/02/18/74215.html
posted @
2009-03-12 13:59 Sandy 阅读(167) |
评论 (0) |
编辑 收藏
今天在项目中遇到了一个问题:在smartphone上获取进程地址不成功,而在pocket pc上却可以获取成功。研究了一下,这是跟smartphone上的安全机制有关,需要对我们的应用程序进行签名。
开发的时候利用数字签名就可以解决。
开发的时候,在Project->Property->Configuration Properties->Authenticode Signing中需要加载开发安全证书。
这样我们就可以很方便的获得进程的路径
TCHAR szPath[MAX_PATH];
HANDLE hProcess = OpenProcess(0, FALSE, pe.th32ProcessID);
GetModuleFileName((HMODULE)hProcess, szPath, sizeof(szPath));
CloseHandle(hProcess);
如果hProcess为NULL的话,获取的是当前进程的路径。
所以开发SmartPhone时需要注意这点。涉及特权API了,就需要签名了。
posted @
2009-03-11 17:52 Sandy 阅读(1695) |
评论 (2) |
编辑 收藏
最近在工作中遇到一个比较怪异的现象,在某些省区与SP的短信交互存在问题,短信发送不出去。查了一下原因:SmsSendMessage参数设置的问题。
在Windows Mobile 5.0SDK的HelloSMS例子中,发送短信的代码是这样写的
void SendSMS(BOOL bSendConfirmation, BOOL bUseDefaultSMSC, LPCTSTR lpszSMSC, LPCTSTR lpszRecipient, LPCTSTR lpszMessage)
{
SMS_HANDLE smshHandle;
SMS_ADDRESS smsaSource;
SMS_ADDRESS smsaDestination;
TEXT_PROVIDER_SPECIFIC_DATA tpsd;
SMS_MESSAGE_ID smsmidMessageID;
// try to open an SMS Handle
if(FAILED(SmsOpen(SMS_MSGTYPE_TEXT, SMS_MODE_SEND, &smshHandle, NULL)))
{
MessageBox(NULL,
(LPCTSTR)LoadString(ghInstance, IDS_ERROR_SMSOPEN, 0, 0),
(LPCTSTR)LoadString(ghInstance, IDS_CAPTION_ERROR, 0, 0),
MB_OK | MB_ICONERROR);
return;
}
// Create the source address
if(!bUseDefaultSMSC)
{
smsaSource.smsatAddressType = SMSAT_INTERNATIONAL;
_tcsncpy(smsaSource.ptsAddress, lpszSMSC, SMS_MAX_ADDRESS_LENGTH);
}
// Create the destination address
smsaDestination.smsatAddressType = SMSAT_INTERNATIONAL;
_tcsncpy(smsaDestination.ptsAddress, lpszRecipient, SMS_MAX_ADDRESS_LENGTH);
// Set up provider specific data
memset(&tpsd, 0, sizeof(tpsd));
tpsd.dwMessageOptions = bSendConfirmation ? PS_MESSAGE_OPTION_STATUSREPORT : PS_MESSAGE_OPTION_NONE;
tpsd.psMessageClass = PS_MESSAGE_CLASS1;
tpsd.psReplaceOption = PSRO_NONE;
tpsd.dwHeaderDataSize = 0;
// Send the message, indicating success or failure
if(SUCCEEDED(SmsSendMessage(smshHandle, ((bUseDefaultSMSC) ? NULL : &smsaSource),
&smsaDestination, NULL, (PBYTE) lpszMessage,
_tcslen(lpszMessage) * sizeof(TCHAR), (PBYTE) &tpsd,
sizeof(TEXT_PROVIDER_SPECIFIC_DATA), SMSDE_OPTIMAL,
SMS_OPTION_DELIVERY_NONE, &smsmidMessageID)))
{
MessageBox(NULL,
(LPCTSTR)LoadString(ghInstance, IDS_SMSSENT, 0, 0),
(LPCTSTR)LoadString(ghInstance, IDS_CAPTION_SUCCESS, 0, 0),
MB_OK);
}
else
{
MessageBox(NULL,
(LPCTSTR)LoadString(ghInstance, IDS_ERROR_SMSSEND, 0, 0),
(LPCTSTR)LoadString(ghInstance, IDS_CAPTION_ERROR, 0, 0),
MB_OK | MB_ICONERROR);
}
// clean up
VERIFY(SUCCEEDED(SmsClose(smshHandle)));
}
这段代码在一般情况下是运行正确的,对于手机与手机的发送是不存在问题的,但是与SP的交互在某些省区就存在短信发送不出去的情况。
为了更好的理解这段代码,我们先来熟悉一下SmsSendMessage及各个参数。
SmsSendMessage
功能:Use the SmsSendMessage function to create and send an Short Message Service (SMS) message.(创建和发送短信,但短信发送后并不保存到发件箱中)
原型:
HRESULT SmsSendMessage (
const SMS_HANDLE smshHandle, // 调用SmsOpen时获得的短信句柄
const SMS_ADDRESS * const psmsaSMSCAddress, //指向短信中心号码的地址
const SMS_ADDRESS * const psmsaDestinationAddress, // 发送的目的地址
const SYSTEMTIME * const pstValidityPeriod, // 发送时间的有效期
const BYTE * const pbData, // 信息的内容部分
const DWORD dwDataSize,// 信息内容的长度
const BYTE * const pbProviderSpecificData, //运营商的附加数据
const DWORD dwProviderSpecificDataSize, // 附加数据的长度
const SMS_DATA_ENCODING smsdeDataEncoding, // 短信编码
const DWORD dwOptions, // 其他选项
SMS_MESSAGE_ID * psmsmidMessageID); // 用于得到系统回执的信息
(具体介绍可查看http://msdn.microsoft.com/en-us/library/aa455068.aspx)
在实际应用中短信发送不出去,但是SmsSendMessage的返回值是S_OK值。在一些文章中有人这样认为是短信编码的问题造成的。
如果编码格式不对可能造成短信中心网关把短信给吞掉的情况,程序虽然调用成功,但是就是目标号码收不到短信。函数参数中的后三个参数可以不用或设默认值都可以。
起初我也是认为这个地方造成的,很是兴奋。短信的回复内容恰为字母,我误以为短信内容此时是7-BIT的短消息,短信网关把短信给吞掉了,造成目标号码收不到短信。在练习中却也阴差阳错的成功了。很高兴的把理由归到了这个地方。并这样总结:SmsSendMessage可以支持7-bit的ASCII码的短消息,也支持16-bit的unicode的短消息。但内容为ASCII的时候,短信编码为 SMSDE_GSM或SMSDE_OPTIMAL,当内容不全是ASCII的时候,短信编码为SMSDE_GSM或SMSDE_OPTIMAL。所以回复内容改为汉字即可。
但是这样对么?起初我认为我的解释很合理.但是我却发现我的一个参数与原来的程序不一样.
是我在尝试中无意修改了一个参数,将
tpsd.psMessageClass = PS_MESSAGE_CLASS1;
修改为了
tpsd.psMessageClass = PS_MESSAGE_CLASSUNSPECIFIED;
这是发送短信中的运营商的指定数据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.
它有以下五个值:
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. (被接受后立即显示但不存储(称为闪信)。需要向SMSC发送确认信息。)
PS_MESSAGE_CLASS1:The message should be stored and an acknowledgement should be sent to the Service Center when it is stored.(接收后被存储,一旦存储,需要向SMSC发送确认信息。)
PS_MESSAGE_CLASS2:The message should be transferred to the SMS data field in the subscriber identity module (SIM) before an acknowledgement is sent to the Service Center.
PS_MESSAGE_CLASS3:When the message has successfully reached the destination and can be stored, an acknowledgement is sent to the Service Center.
PS_MESSAGE_CLASSUNSPECIFIED:The message Class is not set in the outgoing or incoming message. (对发出或收到的短信不进行设置)
分析以上五个值,前四个值有一个共同的特点,都需要向SMSC发送确认。而最后一个值没有设定。
这个值的改动,解决了我所遇到的问题。但究其原因,我有些想不通为什么?
但是在实际应用中,出现了tmail.exe的异常。不知道是这个值的变动带来的问题,还是实际模块中存在的问题。还需要继续研究一下。
如果大家有知道的,给些建议哈.
posted @
2009-03-10 14:14 Sandy 阅读(6716) |
评论 (13) |
编辑 收藏
前阶段在调研mobile上的内存释放问题,根据大家的建议尝试了一些,但是没有什么效果。
于是跑到MSDN上去问相关的问题,得到了一些解答。
As far as I know, I don't think there is other way to meet your requirement. Since each mobile application has 32M memory limitation, we have to do the performance manually, like deleting object which is not used and allocating Large Memory Blocks in Large memory Area.
For more information:
Windows CE .NET Advanced Memory Management
How the Windows Mobile 5.0 Shell Handles Low Memory Situations
我看了一部分,在How the Windows Mobile 5.0 Shell Handles Low Memory Situations中提到,
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.
我对这段话的理解是:当空闲内存小于Hibernate时,系统便会尝试释放内存。首先他会向所有有效的程序发送WM_HIBERNATE。应用程序收到该消息后,会尽量释放资源来释放内存。如果还低于这个值的话,将发送WM_CLOSE消息给最近很少使用的程序。如果还低于该值的,就强行关闭该程序了。
这个方法似乎有效,但是用户再起来程序的话,还是一样的效果,并不是达到了什么释放内存的效果。如何记录最近很少使用的程序,这个是不是有什么方法获得呢?
就可以像系统提示的那样,内存不足,请释放一些内存。手工做一些比较好。
也看了一些相近的程序的做法,似乎效果也没有大家说的那么好。
在How the Windows Mobile 5.0 Shell Handles Low Memory Situations的最后,这样写的
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:
#define MIN_MEMORY_TO_RUN 2*1024*1024
MEMORYSTATUS mst;
mst.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&mst);
If (mst.dwAvailPhys < MIN_MEMORY_TO_RUN)
{
// Try to free memory by asking Shell to shutdown apps
if (!SHCloseApps(MIN_MEMORY_TO_RUN))
{
// Handle the case where memory could not be freed
…
专门查了一下
SHCloseApps的用法
原型:BOOL SHCloseApps( DWORD dwMemSought);
功能:This function tries to free up memory for an application. If necessary, the shell closes down other applications by sending
dwMemSought);
功能:This function tries to free up memory for an application. If necessary, the shell closes down other applications by sending
WM_CLOSE messages.
参数:
dwMemSought Specifies, in bytes, the amount of memory to be freed.
通过了解
dwMemSought Specifies, in bytes, the amount of memory to be freed.
通过了解
SHCloseApps,我们就明白了上面那段代码什么意思了。
看来,内存释放并不是真正意义上的内存整理,看来我有的地方误解了!
posted @
2009-03-05 13:56 Sandy 阅读(1273) |
评论 (2) |
编辑 收藏