换到 Typecho 的其中一个原因就是简洁,以至于撰写界面完全没有编辑器,就是一个 <textarea>
放在那里。当然,如果仅仅如此的话,为了排下版就得手动写 HTML 写得眼花缭乱真有点扛不住,于是就找了个 Markdown 插件来用。
由于之前略懂过一下 Markdown,隐约记得插链接的完整语法是相对来说比较复杂的:
[链接文字](URL "可选的提示文本")
举个例子应用到文章中可能就变成了:
自从2011年5月改版以来,[B站](http://bilibili.tv "Bilibili")采用了和[A站](http://acfun.tv "AcFun")不同的视频推荐方式。
至少在编辑界面看着还是略瞎的。于是,仔细看了 Markdown Readme 后发现上面这个语法是内联式(inline)插入,Markdown 中插入链接还另有一个引用式(reference)链接:
[链接文字][可选的标识]
[可选的标识或链接文字]: URL "可选的提示文本"
改写一下之前的例子就是:
自从2011年5月改版以来,[B站][]采用了和[A站][]不同的视频推荐方式。
[A站]: http://acfun.tv "AcFun"
[B站]: http://bilibili.tv "Bilibili"
或者
自从2011年5月改版以来,[B站][1]采用了和[A站][2]不同的视频推荐方式。
[1]: http://acfun.tv "AcFun"
[2]: http://bilibili.tv "Bilibili"
因为链接正文和链接定义两部分可以分开,类似于参考文献的格式,所以即便是纯文本方式下看着也很舒服。实际上,Markdown 的 Readme 里也是这么说的:
The point of reference-style links is not that they’re easier
to write. The point is that with reference-style links, your
document source is vastly more readable.
说来,写 C/C++ 的程序,由于指针的存在,程序崩溃什么的也就没什么大惊小怪的了。人非圣贤,孰能无过嘛,而且个人觉得程序崩溃比出现错误的结果好调试多了:在 Visual Studio 里 Debug 版本 F5 调试运行直接可以断在崩溃的地方,方便调试。但 Release 版本就没这么幸运了 :(
如果说单纯是是调试 Release 版本,我只用过《游戏之旅》中介绍的勾选 Linker 选项中的 Generate Map File,然后通过崩溃提示信息中提供的 EIP
查这个 Map File 找到崩在哪个函数里,兴致高一点的根据反汇编一步步走下去兴许还能知道是崩在哪句上 :)
不过说到最终交付出去的程序,面对可能存在的各种未知问题,还是生成 Dump 文件,把崩溃那一刻的信息写进文件以供日后分析比较靠谱。
捕捉未捕获的异常
好吧,Windows API 提供了 SetUnhandledExceptionFilter
函数来设置在发生未捕获的异常时调用的回调函数(仅在程序不处于调试运行时调用)。例如设置 CrashCallback
函数:
#include <windows.h>
LONG WINAPI CrashCallback(EXCEPTION_POINTERS *exceptionInfo)
{
// 崩溃处理
return EXCEPTION_EXECUTE_HANDLER;
}
int main()
{
SetUnhandledExceptionFilter(CrashCallback);
// 程序段
}
回调时传入的参数 exceptionInfo
保存了关于该异常的详细信息,不过 Dump 的输出可以不需要亲自干预太多。
生成 Dump 文件
利用上面回调中给出的 EXCEPTION_POINTERS
结构指针提供的信息,MiniDumpWriteDump
函数即可按要求输出一个 Dump 文件内容,其原型:
BOOL WINAPI MiniDumpWriteDump(
HANDLE hProcess, // Dump 目标进程句柄
DWORD ProcessId, // Dump 目标进行 ID
HANDLE hFile, // 输出文件句柄
MINIDUMP_TYPE DumpType, // 输出类型,决定输出哪些内容
MINIDUMP_EXCEPTION_INFORMATION *ExceptionParam,
MINIDUMP_USER_STREAM_INFORMATION *UserStreamParam,
MINIDUMP_CALLBACK_INFORMATION *CallbackParam
);
输出 Dump 文件的内容根据 DumpType
参数变化,详见 MSDN 关于 MINIDUMP_TYPE
的条目。这里举例输出一个最小的 Dump 文件:
HANDLE hFile = CreateFile(TEXT("filename.dmp"), GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) {
MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = exceptionInfo;
mdei.ClientPointers = FALSE;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hFile, MiniDumpNormal, &mdei, NULL, NULL);
CloseHandle(hFile);
}
需要注意的是,MiniDumpWriteDump
等声明在 DbgHelp.h
中,需要链接 DbgHelp.lib
。当然也可以自行从 DbgHelp.dll
中 LoadLibrary
之。
Dump 文件的使用
Dump 文件是可以用 WinDbg 打开的,不过因为手头没有这东西所以没有试过 =3=
Dump 文件也可以用 Visual Studio 打开,而且(似乎)方便一些:把 dmp 文件、exe 文件、pdb 文件放在同一目录中,然后用 Visual C++ 打开 dmp 文件即出现 Minidump File Summary 页面。可以查看异常信息,或者使用右侧的调试按钮开始调试运行并直接断在崩溃处。
以上,就是好久以来的流水帐……
前阵子因为要折腾 VPS 的缘故把博客暂时放在了 @likounin 童鞋的服务器上,不想最近他的服务器出了点问题,于是只能赶紧把 VPS 重新折腾回原样,然后把博客搬回来。
慌忙折腾之中遇到个问题:在 SSH 里卡住了,没法 Ctrl-C
(因为这种按键会直接发给远端),该怎么正常退出?
想来也应该有个转义序列可以直接对 SSH 做操作……于是,那就是 ~
键。
SSH 到服务器后,确保之前按过一次回车,然后按 ~?
,就会列出一堆可用的转义序列,比如:
Supported escape sequences:
~. - terminate connection
~B - send a BREAK to the remote system
~C - open a command line
~R - Request rekey (SSH protocol 2 only)
~^Z - suspend ssh
~# - list forwarded connections
~& - background ssh (when waiting for connections to terminate)
~? - this message
~~ - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)
总之,要退出已经卡住的 SSH 程序,可以在按一次回车(见上面帮助信息的最后一行)之后,按下 ~.
。
话说回来,转义字符也只是默认是这个 ~
字符而已,如果不喜欢的话,ssh_config
文件中有一个选项叫 EscapeChar
可以修改转义字符。
以上。
于是又是一篇木有技术含量的笔记。
对于 Unicode 窗口,WM_IME_CHAR
和 WM_CHAR
没有区别,wParam
都是一个 WCHAR
,即输入的字符。
对于非 Unicode (DBCS) 窗口,WM_IME_CHAR
的 wParam
即由输入法生成的一个字符。这个字符既有可能是单字节字符也有可能是双字节字符。如果是单字节字符,那么和 WM_CHAR
没什么区别;如果是一个双字节字符,那么 wParam
高 8 位为 Leading byte,低 8 位为 Continuation Byte。
所有经由输入法产生的字符都会产生 WM_IME_CHAR
消息而不是 WM_CHAR
,但 DefWindowProc
会把 WM_IME_CHAR
转换为相应的一个或两个 WM_CHAR
消息。
例如:
- 不开输入法输入「9」 → 收到
WM_CHAR
(0x0039)
- 打开输入法输入「9」 → 收到
WM_IME_CHAR
(0x0039) → 收到 WM_CHAR
(0x0039)
- 打开输入法输入「笨」 → 收到
WM_IME_CHAR
(0xB1BF) → 收到 WM_CHAR
(0x00B1) → 收到 WM_CHAR
(0x00BF)
微软什么的最讨厌啦~写个 GUI 程序要么带个控制台窗口,要么就得用非主流的 WinMain
函数作入口。
用 gcc 的话,这其实不是个问题,带上一个 -mwindows
参数即可顺利解决掉控制台窗口并且抛弃 WinMain
。
而到了 Visual Studio,似乎很两难:
- Linker 参数中 SubSystem 选择 Windows 可以去除控制台窗口,但会要求用
WinMain
作入口。
- Linker 参数中 SubSystem 选择 Console 可以使用
main
作入口,但会自带控制台窗口。
于是困惑了。好在今天在 Irrlicht 的教程中见到了解法:
Linker 参数中的 SubSystem 继续选择 Windows,与此同时将 Entry Point 设置为 mainCRTStartup 即可兼得鱼和熊掌。
以命令行参数形式就是:/SUBSYSTEM:windows /ENTRY:mainCRTStartup
要点就是 ENTRY 参数有三种:mainCRTStartup、WinMainCRTStartup、和 _DllMainCRTStartup,分别对应调用 main
、WinMain
、和 DllMain
,默认是根据 /DLL 和 /SUBSYSTEM 参数自动选择的。
以上。
- «
- 1
- ...
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- »