显示标签为“windows”的博文。显示所有博文
显示标签为“windows”的博文。显示所有博文

2011年7月21日星期四

cygwin 与 emacs

讨论emacs和cygwin的关系,当然是在Windows下。emacs分支很多,这里具体指的是Gnu Emacs,并不是使用cygwin中附带的emacs。

(1)
在没有cygwin之前,emacs中 M-x ediff 之类命令不能使用的,因为emacs找不到相应的程序。安装cygwin之后,只要把cygwin加入到PATH中,就可以使用啦。

(2)
再谈另外一个问题。
emacs中要使用cygwin提供的类unix路径表示,需要插件cygwin-mount.el,可以到emacswiki去下载。

(3)
关于使用cygwin的终端,这里是我的一点小经验。

但可能也需要在emacs中使用shell,这不是一个简单的问题。通常有三种方法,在emacs中使用shell。一种是M-x term, 使用终端模拟器;一种是M-x shell,使用 shell mode;还有一种是M-x eshell,使用 eshell mode。

M-x term 在 windows下不能运行,所以忽略不计。在linux下,配合multi-term插件,term是个很不错的选择。

shell mode 可以运行,在没有其他任何设置情况下,用的是windows自带的cmd.exe。你可能想到把它替换成cygwin带的bash.exe。是的,网上也很多这样的设置。这样设置后,在我这里,它表现的很糟糕。首先一个问题是乱码,并不是满屏乱码,而是在 ls 后总会带一些类似"~<$g["的一行很讨厌的尾巴,让人极其抓狂。第二个问题是shell mode 是个文本,所以你要用终端的那种方式去操作,刚开始会感觉到很不适应。第三个问题是中文的支持。中文显示是可以的,但是对于目录名或者文件名中有中文时,不能正确补全,甚至于都不能执行。比如 "cd 目录",就会说找不到"目录"这个路径。
或者你想不换成bash,还是用cmd。那第一个问题就不是问题,乱码在cmd下是不存在的。第二个问题是习惯问题,可以慢慢去适应。第三个问题仍然存在,很闹心。

看起来eshell是个唯一的选择,至少在windowsx下是如此。eshell是emacs自带的用elisp写的一个模式,所以它的传说中的缺点是比较慢,可能经不起大量的操作(是的,我也不知道我在说什么)。eshell也不是尽善尽美,对中文支持还是有些问题(打开有文件名有中文的文件时,中文会乱码,提示找不到该文件),但还是处在可以忍受的地步,至少"cd 目录"可以执行,以及补全也做的不错。

2011年6月26日星期日

Cygwin

前天刚安装MSYS,用得还没上手,就又看上了Cygwin,谁叫Cygwin 软件比较多呢。这种该也是浪费时间的一种方式吧。
安装Cygwin用的是学校的安装源,速度还算可以吧。我的环境是Win XP SP3 英文版,Language for non-unicode选了Chinese PRC。

(1) terminal的选择
没怎么用过终端,Ubuntu下自带的Gnome Terminal 都说很差劲,我倒觉得挺华丽和方便的,说明我对终端的使用程度不高,还没有培养出审美能力。

a. rxvt
推荐比较多的是用rxvt,好吧,那就用rxvt吧。配置rxvt显示中文就让我焦头烂额了一整天,结果还是没有搞好。最多只能显示中文,但是无法输入中文。我失败的配置如下:

~/.bashrc 中添加

#中文环境
#设置完可以显示中文
export LC_CTYPE=zh_CN.GB2312
export LANG=zh_CN.GB2312


#ls 显示颜色
alias ls='ls --color --show-control-chars'

网上的说法是要使rxvt能够输入中文,在~/.inputrc中添加:
set meta-flag on
set convert-meta off
set input-meta on
set output-meta on

我试过,没效果。在这上面浪费了我好多时间。不过,在 ~/.inputrc中添加

set completion-ignore-case on
能使终端忽略大小写。

b. urxvt
还有个推荐说是urxvt,也就是rxvt的unicode版。在cygwin中,这是需要X 环境的。我没安装。
待实验。

c. mintty
这是我现在用的终端,是在cygwin的安装源中。无需设置,即可方便显示中文和输入中文。我让ls 显示颜色以及忽略大小写。

d. cmd
为什么不直接用cmd.exe 开 bash 呢? 也是无需设置显示中文和输入中文。但是,我不知道为什么我不用,或许是装13。

(2) Home路径设置
默认情况下,Home路径在/home/yourname,而/就是cygwin安装目录。很显然,你不会真把这个目录当作home目录,文件全存放在这吧?可以手动修改/etc/passwd文件来设置你喜欢的目录,路径格式使用cygwin风格,比如d:/tizzy目录,在此处应该为/cygdrive/d/tizzy 。

(3) 调用其他程序
居然cygwin是在windows上,说明windows上也有一些你比较顺手的程序,或者已经懒得去用cygwin中类似功能的程序。

为了能够在终端中调用,把每个程序的路径加入到PATH,我是直接加在系统PATH中。然后在目录下建个文件,起个你喜欢的名字,用来启动程序。比如:

我在widnows下用PDFXCview.exe来阅读pdf,安装路径在D:\Program Files\Tracker Software\PDF Viewer,把这个路径加入到系统PATH,在目录下建 pdfview 文件(是的,没有后缀),文件内容为
#!/bin/sh
run PDFXCview.exe "$@"
这样,就可以在终端中用pdfview 来打开pdf了。当然,你也可以不写pdfview文件,而用pdfxcview来启动,但是,这个名字很难记,是不是?!

update:Jun 30,2011
本来以为上面设置就可以,后来打开pdf只能显示第一页,不知道原因。如果直接调用windows下的程序(因为已加入到PATH中),是可以正常打开,但是会占用一个终端,这是我不希望看到的。
实际上,cygwin提供了一个命令 cygstart,可以用来打开任何文件,默认会调用windows下的关联程序来打开,而且不占用终端。这正是我所需要的。

2011年6月24日星期五

MSYS 设置

Minimal GNU(POSIX)system on Windows,是一个小型的GNU环境,包括基本的bash ,make等等。Windows下最优秀的GNU环境(CygWin算什么啊?)。

I. 中文乱码解决方案

(1)ls显示中文不正常解决方法:
/etc/profile 中 添加
alias ls='ls --show-control-chars -F --color=tty'
(2)输入中文不正常解决方法:
在 /etc/inputrc.default 及 ~/.inputrc 中更改
set meta-flag on
set input-meta on
set output-meta on
set convert-meta off


II. 配置字体及颜色
可以通过C:\msys\1.0\msys.bat这个文件来修改,即安装路径下的msys.bat文件。
查找:


start rxvt -backspacekey -sl 2500 -fg %FGCOLOR% -bg %BGCOLOR% -sr -fn Courier-12 -tn msys -geometry 80×25 -e /bin/sh –login -i
可以修改为:

start rxvt -backspacekey -sl 2500 -fg white -bg black -sr -fn Courier-bold-14 -tn msys -geometry 100×40 -e /bin/sh –login -i
这些属性值都可以随便自己设定,不过这一行一定要作为一行来保存!


字体如果使用truetype,界面会变得更丑,比如Courier New 。所以我还是老实使用默认的Courier。


III. 使用其他程序
在MSYS中提供了一些便利的unix-like工具,但你可能在windows下也有一些常用的工具,比如word,或者播放器之类的。这时可能通过编写脚本,使得在rxvt中能够直接调用这些工具。
看下面两个例子
在/bin 目录下添加/bin/splayer 文件,文件内容为:

#! /bin/sh
/d/Program\ Files/SPlayer/splayer.exe "$@"

在/bin目录下添加/bin/pdfview 文件,文件内容为:

#! /bin/sh
/d/Program\ Files/Tracker\ Software/PDF\ Viewer/pdfxcview.exe "$@"


这样,在rxvt中就可以通过 splayer 和 pdfview 调用 播放器和pdf阅读器了。

2011年5月17日星期二

WS_POPUP WS_OVERLAPPED WS_CHILD

WS_POPUP WS_OVERLAPPED WS_CHILD

  Overlapped Windows

An overlapped window is a top-level window that has a title bar, border, and client area; it is meant to serve as an application's main window. It can also have a window menu, minimize and maximize buttons, and scroll bars. An overlapped window used as a main window typically includes all of these components.

  By specifying the WS_OVERLAPPED or WS_OVERLAPPEDWINDOW style in the CreateWindowEx function, an application creates an overlapped window. If you use the WS_OVERLAPPED style, the window has a title bar and border. If you use the WS_OVERLAPPEDWINDOW style, the window has a title bar, sizing border, window menu, and minimize and maximize buttons.

Pop-up Windows

  Pop-up windows are top-level windows and are connected to the desktop window's child windows list. Applications usually use pop-up windows for dialog boxes. The main difference between pop-up and overlapped windows is that pop-up windows need not have captions and overlapped windows must have captions. When a pop-up window does not have a caption, it can be created without a border. Pop-up windows may own other top-level windows or be owned by other top-level windows or both. All pop-up windows have the WS_CLIPSIBLINGS style, even if it was not specified. Pop-up windows must not be created with the CW_USEDEFAULT value for either the position or the size of the window. Pop-up windows that use CW_USEDEFAULT will exist but will have no size or no position or both. Overlapped windows are usually reserved for your application's main window and, in fact, are sometimes called Main windows or Frame windows. Pop-up windows are usually used to communicate with the user in the form of Dialog boxes and Message boxes.

  A pop-up window is a special type of overlapped window used for dialog boxes, message boxes, and other temporary windows that appear outside an application's main window. Title bars are optional for pop-up windows; otherwise, pop-up windows are the same as overlapped windows of the WS_OVERLAPPED style.

  You create a pop-up window by specifying the WS_POPUP style in CreateWindowEx. To include a title bar, specify the WS_CAPTION style. Use the WS_POPUPWINDOW style to create a pop-up window that has a border and a window menu. The WS_CAPTION style must be combined with the WS_POPUPWINDOW style to make the window menu visible.

  Child Windows

Child windows must have a parent window and are confined to the client area of their parent. This is the major distinction between child windows and overlapped and pop-up windows. Child window parents can be top-level windows or other child windows. Child windows are positioned from their parent window's upper-left corner and not from the upper-left of the screen as are top-level windows. Child windows are clipped to the client area of their parent. Controls in a dialog box are child windows whose parent is the dialog box. Child windows must not be created with the CW_USEDEFAULT value for either the position or size of the window. Child windows that use CW_USEDEFAULT will exist but will have no size or position or both.

  A child window has the WS_CHILD style and is confined to the client area of its parent window. An application typically uses child windows to divide the client area of a parent window into functional areas. You create a child window by specifying the WS_CHILD style in the CreateWindowEx function.

  A child window must have a parent window. The parent window can be an overlapped window, a pop-up window, or even another child window. You specify the parent window when you call CreateWindowEx. If you specify the WS_CHILD style in CreateWindowEx but do not specify a parent window, the system does not create the window.

  A child window has a client area but no other features, unless they are explicitly requested. An application can request a title bar, a window menu, minimize and maximize buttons, a border, and scroll bars for a child window, but a child window cannot have a menu. If the application specifies a menu handle, either when it registers the child's window class or creates the child window, the menu handle is ignored. If no border style is specified, the system creates a borderless window. An application can use borderless child windows to divide a parent window's client area while keeping the divisions invisible to the user.

2011年2月10日星期四

ShowWindow的疑问

本 文:[转寄][转贴][删除][修改][回复][作者:novice][人气:81]
发信人: novice (Android), 信区: VC 
标  题: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月06日23:59:04 星期天), 站内信件 WWWPOST 

BOOL WINAPI ShowWindow( 
  __in  HWND hWnd, 
  __in  int nCmdShow 
); 
中 nCmdShow,MSDN中有这么段话: 
This parameter is ignored the first time an application calls ShowWindow, if  
the program that launched the application provides a STARTUPINFO structure.  
Otherwise, the first time ShowWindow is called, the value should be the  
value obtained by the WinMain function in its nCmdShow parameter. 

要怎么理解??? 

我的理解是,如果我用CreateProcess创建某程序,该程序就是创建个窗口,别无其他功 
能,调用CreateProcess时提供了STARTUPINFO si,并将相应的标志位设置si.dwFlags = 
 STARTF_USESHOWWINDOW,si.wShowWindow = SW_SHOWMINIMIZED. 
这样的话,即使被创建的程序第一次调用ShowWindow时传入参数 SW_SHOWMAXIMIZED ,程 
序也应该刚开始是最小化的。因为按照文档说明,参数该被忽略。 

但实际试验了一下,还是会出现最大化得窗口。不知道我哪里理解错误? 

-- 

本 文:[转寄][转贴][删除][修改][回复][作者:CrLF][人气:7]
发信人: CrLF (CrLF(落羽猫)), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月07日13:26:12 星期一), 站内信件 WWWPOST 

注意认真读文档:if the program that launched the application provides a  
STARTUPINFO structure. 

典型的提供STARTUPINFO的方法如:建立一个快捷方式,通过双击快捷方式启动。 

-- 

本 文:[转寄][转贴][删除][修改][回复][作者:novice][人气:2]
发信人: novice (Android), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月07日21:04:18 星期一), 站内信件 WWWPOST 

调用CreateProcess时,给 STARTUPINFO 赋值,不算提供STARTUPINFO 么? 

-- 


本 文:[转寄][转贴][删除][修改][回复][作者:CrLF][人气:5]
发信人: CrLF (CrLF(落羽猫)), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月08日13:40:44 星期二), 站内信件 WWWPOST 

之前理解错了。查了一下,使用STARTUPINFO 里提供的wShowWindow的条件是: 

第一种情况:ShowWindow的参数设为SW_SHOWDEFAULT 

第二种情况:满足以下条件,系统认定为主窗口: 
1. 设置了 STARTF_USESHOWWINDOW.  
2. 窗口是顶级窗口、无所有者、有WS_CAPTION、不是系统模态窗口 
这种情况下若ShowWindow 的参数为 SW_SHOWNORMAL 或 SW_SHOW,则使用你给定的参数. 
  

于是SW_MAXIMIZE不在此列………… 

好吧,MSDN的文档不全…… 
-- 
※ 来源:・瀚海星云 bbs.ustc.edu.cn・[FROM: 60.18.151.157] 
※ 修改:・CrLF 于 2011年02月09日17:24 修改本文・[FROM: 60.18.151.188]
novice
69307364
本 文:[转寄][转贴][删除][修改][回复][作者:novice][人气:6]
发信人: novice (Android), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月08日16:27:05 星期二), 站内信件 WWWPOST 

不好意思,没明白你的意思。我能理解,在你列举的两种情况下,如果给ShowWindow提 
供SW_SHOWDEFAULT或者SW_SHOWNORMAL使得窗口按照STARTUPINFO的wShowWindow显示。 

我不能明白的是,MSDN文档里说的,第一次调用ShowWindow忽略nCmdShow参数的情况。 
对于“忽略”一词,我的理解是不管传入什么值,它都按照固定的方式显示。 

调用CreateProcess时给STARTUPINFO赋值,不算提供STARTUPINFO么? 

【 在 CrLF (CrLF(落羽猫)) 的大作中提到: 】 
: 之前理解错了。查了一下,使用STARTUPINFO 里提供的wShowWindow的条件是:
: 
: 第一种情况:ShowWindow的参数设为SW_SHOWDEFAULT
: 
: 第二种情况:满足以下条件,系统认定为主窗口:
: 1. 设置了 STARTF_USESHOWWINDOW. 
: 2. 窗口是顶级窗口、无所有者、有WS_CAPTION、不是系统模态窗口
: 3. ShowWindow 的参数为 SW_SHOWNORMAL 或 SW_SHOW. 
: 
: 于是SW_MAXIMIZE不在此列…………
: 
: 好吧,MSDN的文档不全……
-- 
※ 来源:・瀚海星云 bbs.ustc.edu.cn・[FROM: 125.78.224.32] 
※ 修改:・novice 于 2011年02月08日16:28 修改本文・[FROM: 125.78.224.32]
CrLF
53453131364

本 文:[转寄][转贴][删除][修改][回复][作者:CrLF][人气:5]
发信人: CrLF (CrLF(落羽猫)), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月08日18:11:36 星期二), 站内信件 WWWPOST 

不是,我查给你的规则是实际的规则(系统实际是这样做的)。msdn文档写的含糊 :) 

信我查的好了。写msdn文档的人肯定没有写windows的人知道的清楚:P 


【 在 novice (Android) 的大作中提到: 】 
: BOOL WINAPI ShowWindow(
:   __in  HWND hWnd,
:   __in  int nCmdShow
: );
: 中 nCmdShow,MSDN中有这么段话:
: This parameter is ignored the first time an application calls ShowWindow, if 
: the program that launched the application provides a STARTUPINFO structure. 
: Otherwise, the first time ShowWindow is called, the value should be the 
: value obtained by the WinMain function in its nCmdShow parameter.
: 
: 要怎么理解???
: 
: 我的理解是,如果我用CreateProcess创建某程序,该程序就是创建个窗口,别无其他功
: 能,调用CreateProcess时提供了STARTUPINFO si,并将相应的标志位设置si.dwFlags =
:  STARTF_USESHOWWINDOW,si.wShowWindow = SW_SHOWMINIMIZED.
: 这样的话,即使被创建的程序第一次调用ShowWindow时传入参数 SW_SHOWMAXIMIZED ,程
: 序也应该刚开始是最小化的。因为按照文档说明,参数该被忽略。
: 
: 但实际试验了一下,还是会出现最大化得窗口。不知道我哪里理解错误?

-- 
※ 来源:・瀚海星云 bbs.ustc.edu.cn・[FROM: 60.18.151.146]
novice
69307364
本 文:[转寄][转贴][删除][修改][回复][作者:novice][人气:3]
发信人: novice (Android), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月08日20:18:32 星期二), 站内信件 WWWPOST 

那意思是 ShowWindow第一次调用与后续调用没区别? 

【 在 CrLF (CrLF(落羽猫)) 的大作中提到: 】 
: 不是,我查给你的规则是实际的规则(系统实际是这样做的)。msdn文档写的含糊 :)
: 
: 信我查的好了。写msdn文档的人肯定没有写windows的人知道的清楚:P
: 
: 
: 【 在 novice (Android) 的大作中提到: 】
: : BOOL WINAPI ShowWindow(
: :   __in  HWND hWnd,
: :   __in  int nCmdShow
: : );
: : 中 nCmdShow,MSDN中有这么段话:
: : This parameter is ignored the first time an application calls ShowWindow, if 
: : the program that launched the application provides a STARTUPINFO structure. 
: : Otherwise, the first time ShowWindow is called, the value should be the 
: : value obtained by the WinMain function in its nCmdShow parameter.
: : 
: : 要怎么理解???
: : 
: : 我的理解是,如果我用CreateProcess创建某程序,该程序就是创建个窗口,别无其他功
: : 能,调用CreateProcess时提供了STARTUPINFO si,并将相应的标志位设置si.dwFlags =
: (以下引言省略...)

-- 
※ 来源:・瀚海星云 bbs.ustc.edu.cn・[FROM: 125.78.224.32]
CrLF
53453131364

本 文:[转寄][转贴][删除][修改][回复][作者:CrLF][人气:3]
发信人: CrLF (CrLF(落羽猫)), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月09日17:28:30 星期三), 站内信件 WWWPOST 

不不,你还是没明白我的意思。 

首先是,不一定是*第一次*调用ShowWindow~  而是第一次对符合主窗口条件(见上面) 
的窗口调用ShowWindow 的时候。 

这个时候如果你用SW_SHOW或SW_SHOWNORMAL,系统会替换。 

你的程序系统认为它是主窗口了,但是你给的是最大化,系统就不管了~ 

【 在 novice (Android) 的大作中提到: 】 
: 那意思是 ShowWindow第一次调用与后续调用没区别?
: 
: 【 在 CrLF (CrLF(落羽猫)) 的大作中提到: 】
: : 不是,我查给你的规则是实际的规则(系统实际是这样做的)。msdn文档写的含糊 :)
: : 
: : 信我查的好了。写msdn文档的人肯定没有写windows的人知道的清楚:P
: : 
: : 
: : (以下引言省略...)

-- 
※ 来源:・瀚海星云 bbs.ustc.edu.cn・[FROM: 60.18.151.188]
novice
69307364
本 文:[转寄][转贴][删除][修改][回复][作者:novice][人气:5]
发信人: novice (Android), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月09日20:12:03 星期三), 站内信件 WWWPOST 

抱歉在这个问题上纠缠这么久。 

再说说我现在的理解。你的意思是:在满足主窗口条件时,第一次调用ShowWindow时使 
用SW_SHOW或SW_SHOWNORMAL,会使窗口按照STARTUPINFO的信息显示? 

MSDN里文档里说的“忽略”就是上述意思?“This parameter is ignored the first  
time an application calls ShowWindow, if the program that launched the  
application provides a STARTUPINFO structure.”感觉另有深意啊。 

那为什么要称为“ignored”呢? 因为是上述说法的话,那等同于在SW_SHOW或SW_ 
SHOWNORMAL时,使用STARTUPINFO的信息。而其他参数也按照各自本来的效果显示,并没 
有被忽略。 

感觉你的意思是在说明在什么条件下使用STARTUPINFO的信息,而我最大的疑惑是MSDN文 
档里的“忽略”二字。不对之处请指正。 

【 在 CrLF (CrLF(落羽猫)) 的大作中提到: 】 
: 不不,你还是没明白我的意思。
: 
: 首先是,不一定是*第一次*调用ShowWindow~  而是第一次对符合主窗口条件(见上面)
: 的窗口调用ShowWindow 的时候。
: 
: 这个时候如果你用SW_SHOW或SW_SHOWNORMAL,系统会替换。
: 
: 你的程序系统认为它是主窗口了,但是你给的是最大化,系统就不管了~
: 
: 【 在 novice (Android) 的大作中提到: 】
: : 那意思是 ShowWindow第一次调用与后续调用没区别?
: : 
-- 
※ 来源:・瀚海星云 bbs.ustc.edu.cn・[FROM: 222.77.201.102] 
※ 修改:・novice 于 2011年02月09日20:25 修改本文・[FROM: 222.77.201.102]
CrLF
53453131364

本 文:[转寄][转贴][删除][修改][回复][作者:CrLF][人气:2]
发信人: CrLF (CrLF(落羽猫)), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月09日23:00:37 星期三), 站内信件 WWWPOST 

it is "ignored" becuase it is "overridden" :) 

MSDN只是没说识别的细节而已。实际上你从设计意图上理解比较好。它之所以这么设计 
,就是为了让写程序的人不用考虑到底该用什么参数。你只要主窗口的ShowWindow用 
WinMain参数里给定的那个,根本不用考虑这些。如果需要在前面显示对话框,就该是模 
态的。如果同时显示对话框,主窗口一般是所有者……总之,为了方便,你什么都不做 
,交给Windows就好。 

【 在 novice (Android) 的大作中提到: 】 
: 抱歉在这个问题上纠缠这么久。
: 
: 再说说我现在的理解。你的意思是:在满足主窗口条件时,第一次调用ShowWindow时使
: 用SW_SHOW或SW_SHOWNORMAL,会使窗口按照STARTUPINFO的信息显示?
: 
: MSDN里文档里说的“忽略”就是上述意思?“This parameter is ignored the first 
: time an application calls ShowWindow, if the program that launched the 
: application provides a STARTUPINFO structure.”感觉另有深意啊。
: 
: 那为什么要称为“ignored”呢? 因为是上述说法的话,那等同于在SW_SHOW或SW_
: SHOWNORMAL时,使用STARTUPINFO的信息。而其他参数也按照各自本来的效果显示,并没
: 有被忽略。
: 
: 感觉你的意思是在说明在什么条件下使用STARTUPINFO的信息,而我最大的疑惑是MSDN文
: 档里的“忽略”二字。不对之处请指正。
: 
: 【 在 CrLF (CrLF(落羽猫)) 的大作中提到: 】
: : 不不,你还是没明白我的意思。
: : 
: : 首先是,不一定是*第一次*调用ShowWindow~  而是第一次对符合主窗口条件(见上面)
: (以下引言省略...)
-- 
※ 来源:・瀚海星云 bbs.ustc.edu.cn・[FROM: 60.18.151.188] 
※ 修改:・CrLF 于 2011年02月09日23:08 修改本文・[FROM: 60.18.151.188]
novice
69307364
本 文:[转寄][转贴][删除][修改][回复][作者:novice][人气:0]
发信人: novice (Android), 信区: VC 
标  题: Re: ShowWindow 的疑问 
发信站: 瀚海星云 (2011年02月10日09:59:17 星期四), 站内信件 WWWPOST 

it is "ignored" becuase it is "overridden" 。了解了。 

哦哦,那结论是第一次调用时乖乖用WinMain的nCmdShow啦。 

多谢! 

【 在 CrLF (CrLF(落羽猫)) 的大作中提到: 】 
: it is "ignored" becuase it is "overridden" :)
: 
: MSDN只是没说识别的细节而已。实际上你从设计意图上理解比较好。它之所以这么设计
: ,就是为了让写程序的人不用考虑到底该用什么参数。你只要主窗口的ShowWindow用
: WinMain参数里给定的那个,根本不用考虑这些。如果需要在前面显示对话框,就该是模
: 态的。如果同时显示对话框,主窗口一般是所有者……总之,为了方便,你什么都不做
: ,交给Windows就好。
: 
: 【 在 novice (Android) 的大作中提到: 】
: : 抱歉在这个问题上纠缠这么久。
: : 
: : 再说说我现在的理解。你的意思是:在满足主窗口条件时,第一次调用ShowWindow时使
: : 用SW_SHOW或SW_SHOWNORMAL,会使窗口按照STARTUPINFO的信息显示?
: : 
: : MSDN里文档里说的“忽略”就是上述意思?“This parameter is ignored the first 
: : time an application calls ShowWindow, if the program that launched the 
: : application provides a STARTUPINFO structure.”感觉另有深意啊。
: : 
: : 那为什么要称为“ignored”呢? 因为是上述说法的话,那等同于在SW_SHOW或SW_
: : SHOWNORMAL时,使用STARTUPINFO的信息。而其他参数也按照各自本来的效果显示,并没
: (以下引言省略...)

2011年1月10日星期一

VC++ 2005 Express + SDK

You can use Visual C++ Express to build powerful .NET Framework applications immediately after installation. In order to use Visual C++ Express to build Win32 applications, you'll need to take just a few more steps. I'll list the steps necessary for building Win32 applications using Visual C++ Express.

Step 1: Install Visual C++ Express.


If you haven't done so already, install Visual C++ Express.


Step 2: Install the Microsoft Platform SDK.

Install the Platform SDK over the Web from the Download Center. Follow the instructions and install the SDK for the x86 platform.


Step 3: Update the Visual C++ directories in the Projects and Solutions section in the Options dialog box.

From the Tools menu in Visual Studio, select Options. The Options dialog box appears.

From the Options dialog box, expand the Projects and Solutions node and select VC++ Directories. In that section, add the following paths to the appropriate subsection:

    * Executable files: C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Bin
    * Include files: C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include
    * Library files: C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib

Note: Alternatively, you can update the Visual C++ Directories by modifying the VCProjectEngine.dll.express.config file located in the \vc\vcpackages subdirectory of the Visual C++ Express install location. Please make sure that you also delete the file "vccomponents.dat" located in the "%USERPROFILE%\Local Settings\Application Data\Microsoft\VCExpress\8.0" if it exists before restarting Visual C++ Express Edition.


Step 4: Update the corewin_express.vsprops file.

One more step is needed to make the Win32 template work in Visual C++ Express. You need to edit the corewin_express.vsprops file (found in C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults) and

Change the string that reads:

AdditionalDependencies="kernel32.lib"

to

AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib"


Step 5: Generate and build a Win32 application to test your paths.

In Visual C++ Express, the Win32 Windows Application type is disabled in the Win32 Application Wizard. To enable that type, you need to edit the file AppSettings.htm file located in the folder %ProgramFiles%\Microsoft Visual Studio 8\VC\VCWizards\AppWiz\Generic\Application\html\1033\".

In a text editor comment out lines 441 - 444 by putting a // in front of them as shown here:

// WIN_APP.disabled = true;
// WIN_APP_LABEL.disabled = true;
// DLL_APP.disabled = true;
// DLL_APP_LABEL.disabled = true;

Save and close the file and open Visual C++ Express.

From the File menu, click New Project. In the New Project dialog box, expand the Visual C++ node in the Product Types tree and then click Win32. Click on the Win32 Console Application template and then give your project a name and click OK. In the Win32 Application Wizard dialog box, make sure that Windows application is selected as the Application type and the ATL is not selected. Click the Finish button to generate the project.

As a final step, test your project by clicking the Start button in the IDE or by pressing F5. Your Win32 application should build and run.

参考译文:

安装之后,您可以立即使用Visual C++ 2005速成版来生成功能强大的.NET Framework 应用程序。若要使用 Visual C++ 速成版生成Win32应用程序,只需采取几个步骤,下面对此进行了详细介绍。 
   
1. 安装 Platform SDK 以便与 Visual C++ 速成版结合使用从 Platform SDK 更新站点 的 Platform SDK Update 站点通过 Web 安装 Microsoft Platform SDK。在该页上,单击“Download”(下载),然后确保从列表中依次选择“Windows SDK”和“Core SDK”。 

2. 从 Visual Studio 中的“工具”菜单上,选择“选项”。出现“选项”对话框。 
从“选项”对话框中,展开“项目和解决方案”节点并选择“VC++ 目录”。在该部分,将以下路径添加到相应的子节: 
可执行文件:C:\Program Files\Microsoft SDK\Bin 
包含文件:C:\Program Files\Microsoft SDK\include 
库文件:C:\Program Files\Microsoft SDK\lib 
    注意 在您的系统上,Platform SDK 的位置可能有所不同。 

3. 更新 corewin_express.vsprops 文件 
(位于C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults 中) 

并将以下字符串: 

AdditionalDependencies="kernel32.lib" 

更改为: 

              AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib" 

注意 在您的系统上,Visual C++ 速成版 可能安装到了不同的位置。 

4. 在Visual C++ 速成版,Win32应用程序向导上的Windows 应用程序选项是不可选的,要使用这个选项,你需要修改AppSettings.htm这个文件,它位于"%ProgramFiles%\ Microsoft Visual Studio 8\VC\VCWizards\AppWiz\Generic\Application\html\1033\". 

在文本编辑器用"// "符号把文件里的441 - 444这几行注释掉,像下面这样: 

// WIN_APP.disabled = true; 

// WIN_APP_LABEL.disabled = true; 

// DLL_APP.disabled = true; 

// DLL_APP_LABEL.disabled = true; 

保存和关闭文件,然后打开Visual C++ 速成版.

2011年1月8日星期六

msvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义

来源:未知

这篇文章要来谈谈程式库 (Library) 连结,以及关于 MSVC 与 CRT 之间的种种恩怨情仇。

如果你使用的作业系统是 Linux、Mac 或其他非 Windows 平台,你可以忽略这篇文章;如果你使用的作业系统是 Windows 平台,但没有用 Microsoft Visual Studio C++(以下简称为 MSVC)软体撰写 C++ 程式的话,这篇文章对你的帮助可能很有限;但如果你的作业系统是 Windows,而且你使用的程式整合开发环境是 MSVC 软体撰写 C++ 程式的话,这篇文章应该能够帮助你釐清一些重要的基础观念。

身为程式设计者,在学习程式设计的过程中,你是否曾经遇过某些看起来不知所云的错误讯息,却不知该如何解决?例如当你快快乐乐地写完程式,并且确认所有的程式码都能成功通过编译之后,接着执行「建置方案」(Build Solution) 的步骤,结果却跑出一堆莫名其妙的错误:

LIBCMTD.lib(mlock.obj) : error LNK2005: __lock 已在 MSVCRTD.lib(MSVCR80D.dll) 中定义过了

LIBCMTD.lib(mlock.obj) : error LNK2005: __unlock 已在 MSVCRTD.lib(MSVCR80D.dll) 中定义过了

LIBCMTD.lib(crt0.obj) : error LNK2005: _mainCRTStartup 已在 MSVCRTD.lib(crtexe.obj) 中定义过了

…………

LINK : warning LNK4098: 预设的程式库 ‘MSVCRTD’ 与其他使用的程式库冲突,请使用 /NODEFAULTLIB:library

LINK : warning LNK4098: 预设的程式库 ‘LIBCMTD’ 与其他使用的程式库冲突,请使用 /NODEFAULTLIB:library

D:\Workspace\CrtLibTest\Debug\CrtLibTest.exe : fatal error LNK1169: 找到有一或多个已定义的符号

以一般的情况来说,如果在你的程式专案中有使用某些由他人所撰写的第三方程式库或是开源专案的程式库,比较容易会发生上述的错误状况。从上述这些看似离奇而令人摸不着头绪的错误讯息中,我们大概可以猜测问题点应该在于 LIBCMTD.lib 与 MSVCRTD.lib 这两个程式库身上。但到底什么是 LIBCMTD.lib 和 MSVCRTD.lib?在我们的程式码中有使用这些程式库吗?

 

答案是肯定的。

熟悉 C 语言的程式设计者都知道,如果要使用 printf()、scanf() 或者 fopen() 等等 C 语言的基本 I/O 操作函式时,首先必须用 #include 语法将 stdio.h 这个标头档纳入我们的程式码中。藉由 stdio.h 中对这些 I/O 操作函式所做出的函式宣告 (function declaration),编译器 (Compiler) 才得以确认 printf、scanf 以及 fopen 等等都是合法可用的函式。

而当我们撰写的程式码经过编译器产出 OBJ 形式的档案之后,需要再经由连结器 (Linker) 的处理程序,将程式码中全部有使用到的函式定义 (function definition) 连结建置起来,才能够产生出最后的程式执行档。问题来了,我们知道 printf、scanf 以及 fopen 的函式宣告存在于 stdio.h 当中,但是这些傢伙的函式定义,也就是真正的实做程式码,究竟存放在什么地方呢?

在 C 语言的标准程式库中。

由 C 语言所制订的标准程式库,称之为「执行阶段程式库」,也就是 C Run-Time Library,通常可简称为 CRT。在 C 语言的标准程式库中,包含了一组常用的基础函式,例如 I/O 处理与字串操作程序等等,所以只要我们使用 C 语言撰写程式码,就一定要将编译完成后的程式码 OBJ 档,连结至 C 语言的执行阶段程式库,才能够产生出合法的 C 语言程式执行档。

而 CRT 并非只有单一一种版本存在。事实上,除了可以依「除错」与「释出」用途分成两个版本之外,两者又可分别衍生分出「静态连结」与「动态连结」两种形式:

静态连结:

LIBCMTD.lib(除错版本)

LIBCMT.lib

动态连结:

MSVCRTD.lib(除错版本)

MSVCRT.lib

虽然这四个 CRT 版本的用途与使用方式各不相同,但却有个共通的特点,就是它们都是满足执行绪安全需求,可在多执行绪程式码中安全使用的程式库版本。事实上,在过去 MSVC 6 的版本中,本来还有另外两个 LIBCD.lib(除错版本)与 LIBC.lib 程式库,是专门给单执行绪程式使用的 CRT 版本,但是这两个选项自 MSVC 2005 开始就从设定选项中被删除掉了,所以现在大多数程式设计者使用的都是多执行绪的 CRT 版本。

在程式库连结 (library linking) 的行为中,静态连结和动态连结的分别,在于使用静态连结时,会直接将程式库的函式定义嵌入执行档之中,而使用动态连结时,程式库的函式定义则存在于另外的独立档案,通常是 DLL 格式的档案中,然后与程式执行档一同发佈给使用者。因此在档案的尺寸上,使用动态连结的执行档档案,通常会比使用静态连结的执行档档案来得更小一些。

使用动态连结 CRT 版本的好处,是能够将经常使用到的标准程式库们独立出来,放在 Windows 的系统资料夹中,以减少我们建置出来的执行档档案尺寸。但反过来说,使用动态连结 CRT 版本的缺点也在于这些与执行档相依为命的 DLL 档案上。举例来说,如果程式以 MSVC 2005 建置出 Debug 组态的执行档,则此执行档需要有 msvcr80d.dll 存在才能顺利执行;如果是 Release 组态,则相依于 msvcr80.dll。但是如果你把相同的程式码拿到 MSVC 2008 上建置,产生出来的执行档则相依于 msvcr90d.dll 与 msvcr90.dll 两个不同的 DLL 档案。不同版本的 MSVC,都会有各自不同的相依 DLL 档案。

在 MSVC 的程式专案中,如何指定程式码要使用静态连结或者动态连结的 CRT 版本?其实很容易,只要在专案属性的「C/C++」页面中,选择「程式码产生」(Code Generation) 子页面,其中有个「执行阶段程式库」(Runtime Library) 的项目,也就是专案中用来设定 CRT 连结版本的地方。其中总共有四个选项,正好对应于上述静态连结与动态连结的四个不同程式库版本。

多执行绪侦错 (/MTd):对应 LIBCMTD.lib

多执行绪 (/MT):对应 LIBCMT.lib

多执行绪侦错 DLL (/MDd):对应 MSVCRTD.lib

多执行绪 DLL (/MD):对应 MSVCRT.lib

如果你没有做任何设定就开始建置程式的话,MSVC 的预设选项则会使用动态连结的版本。


C Runtime Library

请注意,以上只是单纯 C 语言的程式库而没有包含 C++ 语言在内。如果你的程式系统中,有包含 C++ 语言的程式码的话,那又是另外一回事了。但是在专案属性的页面中,为什么找不到相关的设定选项呢?因为 MSVC 悄悄地帮程式设计者代劳处理掉了。只要在程式码中使用 #include 语法纳入任何一个 C++ 的标头档,例如 iostream 或 fstream,MSVC 就会在连结器的运作阶段中,自动帮我们连结 C++ 的执行阶段程式库。而 C++ 的执行阶段程式库,同样可分为四个版本:

静态连结:

LIBCPMTD.lib(除错版本)

LIBCPMT.lib

动态连结:

MSVCPRTD.lib(除错版本):执行档相依于 MSVCP90D.dll

MSVCPRT.lib:执行档相依于 MSVCP90.dll

至于程式执行档使用的是静态连结或者动态连结的版本,就仰赖于 C 语言的版本设定选项了。举个例子来说,如果你撰写了一个 Debug 组态的 C++ 程式,并且保留专案原先预设的建置选项(动态连结),那么最终建置出来的程式执行档将会相依于 MSVCR90D.dll 以及 MSVCP90D.dll 两个 DLL 档案。如果将相同的程式以 Release 组态建置完成,则会相依于 MSVCR90.dll 以及 MSVCP90.dll 二者。


Standard C++ Library

刚学习程式设计的入门者,经常会在满心欢喜地完成一件程式作品并且传给其他人使用时,却发现不能在别人的电脑上启动程式,其实就是陷入了使用者电脑缺少 DLL 档案而无法执行程式的窘境。有三种方法可以解决这个令人困扰的问题:

使用者的电脑,必须先安装「Visual C++ 可转发套件」(MSVC 2008 或 MSVC 2005 )。

将所需的 DLL 档案,例如 MSVCR90D.dll 与 MSVCP90D.dll,直接附在程式的下载包当中。

以静态连结方式建置程式执行档。

当你无法确定自己的程式或别人的程式,是否相依于某些特定的 DLL 档案时,有一个非常好用的免费工具程式 Dependency Walker,可以开启 EXE 格式的执行档或者 DLL 格式的动态程式库,然后详细地条列出它们所相依的 DLL 档案。

瞭解了几种不同的 CRT 版本选项之后,回到最前面的错误讯息问题,相信各位现在应该能够很清楚地理解,原来会发生这些奇怪的错误状况,是因为程式同时连结了 LIBCMTD.lib 与 MSVCRTD.lib 所以造成函式定义版本冲突。也就是说,程式连结器已经在其中一个 CRT 的版本中找到所需的函式定义,但此时却又跳出另外一位 CRT,也给了一份相同函式的实作版本,所以连结器无法判断应该忽略谁并且选择谁。

而这个状况的发生原因,就是你的程式与程式所连结的外部程式库,使用了不同的 CRT 版本之故。例如,当你的程式使用了 Lua,自然必须连结至 Lua 的程式库 lua5.1.lib,但如果 lua5.1.lib 是以静态连结版本的 CRT 建置而成,而你的程式却是以预设选项,动态连结 CRT 来建置程式执行档的话,如此一来就会产生上述这些错误讯息了。至此,问题的答案已昭然若揭,解决方法有二种:其一是将 Lua 重新以动态连结 CRT 的方式建置出一个新的程式库,其二则是将自己的程式专案改成以静态连结 CRT 方式建置。

换个角度想,当你身为一位程式库的设计开发者,想要将自己写的东西分享给其他人,但又不想要完全开放自己撰写的程式源码时,至少可以同时提供以下四种版本的程式库,以妥善满足使用者的各种不同需求:

Debug:动态连结除错版本

Release:动态连结版本

Debug_Static:静态连结除错版本

Release_Static:静态连结版本

然而,有时候世界并不会运作得如此理想。在某些特殊的状况下,当我们使用他人所写的第三方程式库时,有时可能只拿得到其中某个特定的版本,例如 Release_Static 版本时,就很有可能会遇到程式库冲突的错误情形。此时就需要视专案的实际需求而定,可以在专案属性中指定「忽略特定程式库」(Ignore Specific Library) 这个选项,让程式码连结器忽略某些程式库,以此化解动静程式库或新旧程式库之间的恩怨冲突。

小测验:你所撰写的程式,必须连结某个以静态多执行绪 (/MT) CRT 建置而成的程式库。如果你的程式在 Debug 组态下以多执行绪侦错 (/MTd) 选项建置,是否会产生冲突?如果你的程式在 Release 组态下以多执行绪 (/MT) 选项建置,是否会产生冲突?是的话,应该如何解决?

 

 

上面的方法还是不行!会出现其他问题的。

以下是我摸索出的最新的解决方法:

首先,所有的lib文件,使用/MTd或/MT编译。Debug调试模式使用/MTd,Release模式使用/MT。

然后,在自己的程序中也使用/MTd或/MT编译。这样就不会出问题了。

三种编译链接库的方式:

(1)连接Windows库。针对Win32 API编写的应用程序,上面的方法可能带来新问题,可以忽略libcmt.lib库,即可。如果还有其他问题,再忽略相应的库。

(2)MFC静态链接。上面的方法就是针对这种链接方式的,所以没问题。

(3)MFC动态链接。没有试过,应该和(1)类似。

 

最后补充:如果还不行,直接加入/force:multiple编译参数吧。这次之所以没有使用它,也是为了严谨起见。



2010年8月2日星期一

一个小函数,ShowErrMsg

void ShowErrMsg()
{
TCHAR szBuf[80];
LPVOID lpMsgBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

MessageBox(NULL, lpMsgBuf, "系统错误", MB_OK|MB_ICONSTOP);

LocalFree(lpMsgBuf);
}