Google

星期二, 四月 21, 2009

用rsync对网站进行镜像备份(转)

用rsync对网站进行镜像备份

by inburst
http://xfocus.org

对系统管理员来说,平时的工作重心应该集中在维护系统正常运转,能够正常提供服务上,这里往往牵涉到一个数据备份的问题,在我所了解

的情况中,有80%的系统管理员不是太关心自己服务器的安全性,但往往对备分镜像的技术相当感兴趣,但由于商业产品的软硬件价格都相当高

昂,因此往往会选择自由软件。这里准备介绍的rsync就是这样的软件,它可以满足绝大多数要求不是特别高的备份需求。
http://www.xfocus.net/articles/200107/214.html

标签: , , , ,

星期三, 三月 11, 2009

强力推荐Linux下的五大BT下载工具

在Windows操作系统中,可供我们选择的P2P工具多不胜数。然而对于其他操作系统而言,这一类型的软件可能会相对匮乏。俗话说:多不如精。Linux特别是Ubuntu Linux用户拥有的BT软件如果功能足够强大的话,又何必在乎可选择的范围究竟有多宽呢!

  下面,我们将为大家挑选出Ubuntu Linux操作系统中最常用又最好用的五大BT工具。

  1、qBitTorrent

  qBitTorrent是Ubuntu Linux中最受欢迎的P2P软件之一。出自一名法国大学生之手的qBitTorrent功能强大,界面精美,操作直观。

  qBitTorrent是Linux中最受欢迎的P2P软件之一

  qBittorrent的主要特性包括:

  ◆使用Qt4工具包编写出优美的图形用户界面;

  ◆支持UPnP/NAT-PMP端口转发;

  ◆支持加密(与Azureus兼容);

  ◆支持多个文件同时下载或上传;

  ◆集成搜索引擎;

  ◆支持DHT网络;

  ◆支持μTorrent对等交换(PeX);

  ◆支持多达25种语言。

  2、kTorrent

  kTorrent拥有一张漂亮的脸蛋

  KTorrent是使用C++语言为KDE编写的BT客户端程序,其主要功能包括:

  ◆支持UDP追踪;

  ◆IP地址黑名单插件;

  ◆UPnP端口转发(通用即插即用);

  ◆协议加密;

  ◆支持μTorrent对等交换;

  ◆文件优先级别设置;

  ◆导入已部分下载的文件;

  ◆目录扫描,自动监视新的种子文件目录;

  ◆支持RSS。

 3、rTorrent

  rtorrent是利用libtorrent库创建的Ncurses客户端程序。使用C++语言编写的rtorrent除了能够提供基于GUI界面的客户端所具备的功能之外,其速度和效率更为用户所推崇。

  rtorrent的速度和效率更为用户所推崇

  rtorrent的主要功能包括:

  ◆查看下载、开始下载、停止已激活的下载或删除已经停止的下载等;

  ◆调用命令或更改设置;

  ◆更改下载的优先级;

  ◆通过URL或文件路径添加种子,使用标签查看目录内容并自动完成;

  ◆查看日志;

  ◆按空格键退出。

  4、Azureus

  很多Windows用户都知道,以快速高效著称的Azureus是一个基于JAVA的BT客户端软件。其实,Azureus还是一个跨平台的BT下载工具,在Linux操作系统上的应用同样受到了开源社区的青睐。

  Azureus在Windows世界里也颇有名气

  5、Deluge

  Deluge和Azureus一样,不仅仅适用于Linux平台,也适用于其他主流操作系统。

  Deluge也是一个跨平台的BT下载软件

  Deluge的功能同样十分强大,包括:

  ◆Web用户界面;

  ◆BitTorrent协议加密;

  ◆Mainline DHT;

  ◆本地对等发现;

  ◆FAST协议扩展;

  ◆μTorrent对等交换;

  ◆UPn与NAT-PMP

  ◆支持代理服务器;

  ◆全局或单种子速度限制;

  ◆密码保护;

  ◆RSS。
http://linux.chinaunix.net/news/2009/03/11/1064924.shtml

标签: , , ,

星期五, 二月 27, 2009

Simulate the pressing of keyboard keys

type
TBuffers = array [0..1] of TKeyboardState;
var
pKeyBuffers: ^TBuffers;
lParam: LongInt;
begin
(* check if the target window exists *)
if IsWindow(hWindow) then
begin
(* set local variables to default values *)
pKeyBuffers := nil;
lParam := MakeLong(0, MapVirtualKey(key, 0));

(* modify lparam if special key requested *)
if specialkey then
lParam := lParam or $1000000;

(* allocate space for the key state buffers *)
New(pKeyBuffers);
try
(* Fill buffer 1 with current state so we can later restore it.
Null out buffer 0 to get a "no key pressed" state. *)
GetKeyboardState(pKeyBuffers^[1]);
FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0);

(* set the requested modifier keys to "down" state in the buffer*)
if ssShift in shift then
pKeyBuffers^[0][VK_SHIFT] := $80;
if ssAlt in shift then
begin
(* Alt needs special treatment since a bit in lparam needs also be set *)
pKeyBuffers^[0][VK_MENU] := $80;
lParam := lParam or $20000000;
end;
if ssCtrl in shift then
pKeyBuffers^[0][VK_CONTROL] := $80;
if ssLeft in shift then
pKeyBuffers^[0][VK_LBUTTON] := $80;
if ssRight in shift then
pKeyBuffers^[0][VK_RBUTTON] := $80;
if ssMiddle in shift then
pKeyBuffers^[0][VK_MBUTTON] := $80;

(* make out new key state array the active key state map *)
SetKeyboardState(pKeyBuffers^[0]);
(* post the key messages *)
if ssAlt in Shift then
begin
PostMessage(hWindow, WM_SYSKEYDOWN, key, lParam);
PostMessage(hWindow, WM_SYSKEYUP, key, lParam or $C0000000);
end
else
begin
PostMessage(hWindow, WM_KEYDOWN, key, lParam);
PostMessage(hWindow, WM_KEYUP, key, lParam or $C0000000);
end;
(* process the messages *)
Application.ProcessMessages;

(* restore the old key state map *)
SetKeyboardState(pKeyBuffers^[1]);
finally
(* free the memory for the key state buffers *)
if pKeyBuffers <> nil then
Dispose(pKeyBuffers);
end; { If }
end;
end; { PostKeyEx }

http://www.moon-soft.com/doc/42470.htm

标签: ,

小改注册表 轻松实现Windows Live Messenger9.0多开功能

HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows Live;

MultipleInstances,DWORD 值,1


即:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Live\MultipleInstances为MSN内部控制是否允许多重进入的开关。

原文:
http://q.yesky.com/group/review-17643153.html

标签: ,

星期四, 一月 08, 2009

ESC打印机的控制命令

计算机能够完成数值计算、数据处理、图象设计、过程控制等工作都是在一种或多种计算机语言的指挥下进行的。同样,打印机各种部件的运行和动作,各种打印动作的实现、在各种介质上打印出图形和字符,也是由一套能为打印机所识别的语言(命令)来进行控制。通常将能完成上述功能的命令的集合成为打印机控制命令(Print Control Command)为了更好的熟知打印机控制命令,我们需先行了解打印机的数据处理流程。
二、打印机的控制命令
目前主流的打印机控制命令主要有以下三种:
  EPSON公司的ESC PK命令集
  HP公司的PCL命令集
  Adobe公司的PostScript(简称PS)命令集
ESC PK命令集是针式打印机(尤其是滚筒方式打印)领域事实上的工业标准;PCL命令集是中、低档激光打印机、喷墨机印机领域的工业标准;PS命令集则是高档排版、出版领域的应用标准。

1、名词解释

1)控制命令:对打印机进行各种处理和控制动作,并为打印机所识别的命令序列。
2)仿真;控制打印机按照某种控制命令进行工作,就称为这个控制命令的仿真。
3)驱动程序;转换文件成为某种特定控制命令描述的文档,并进行输出的程序。
注:驱动程序就是打印控制命令的形体表现,其本质就是按照某一控制命令的格式,将计算机的数据进行翻译和组织,并形成相应的字符和位图的序列送往打印机。

2、命令分类
打印机控制命令的种类可分为二大类:基本控制命令和扩充命令。

1) 基本命令(Basic Control Code)
基本命令其实就是ASCII码中规定的具有打印功能的控制命令,它的特点是均用一个ASCII码(一个字节)代表,使用比较方便。它的数值范围如下:
ASCII: 00H ~ 20H
2) 扩充命令(Extension Control Command)
基本命令仅提供标准和基本的控制功能。要实现字型大小、各种修饰功能、行与列间距控制、格式设定等较复杂的控制功能,就必须使用扩充命令。扩充命令一般由两个或两个以上的字节组成,其格式有如下几种形式:
Code CH
Code CH1[CH2]
Code CH1[CH2][Parm1 …Parm1]
Code CH1[CH2][Parm1 …Parm1]CH3
Code: 控制命令的引导代码
CH: 表示控制字符
Parm: 系列参数
例: 设定图象打印方式
ASCII码: ESC * m n1 n2
十进制码: 27 42 m n1 n2
十六进制码1B 2A m n1 n2
m: 图象方式
水平密度:60 DPI ~ 360DPI
垂直密度:60 DPI ~ 360DPI
每列点数:8点 ~ 48点
计算公式:列数=n1+n2*256
这里:“ESC“即为该控制命令的引导代码,而“*”和“m”为表示为图象命令的控制命令,“n1,n2”则为图象的系列参数。
3)命令格式类别
作为针式打印机的控制命令类别,有如下几种序列的表示方式:
* ESC序列
* FS序列
* SUB序列
* CEX 序列

3、命令系列

1)针式打印机
(1)ESC/P系列 (Epson)
(2)IBM系列 (IBM)
(3)OKI系列 (OKI)
(4)AR系列 (得实)
(5)PR系列 (南天)
2) 微型打印机
ESC/POS系列 (Epson)
Basic+ESC+GS+FS
3) 激光机
(1)PCL系列 (HP)
(2)ESC/PAGE (EPSON)
(3)Post Script (Adobe)
(4)GDI 方式

三、针式打印机控制命令分析

1、 ESC/P命令系列:
* 应用于滚筒方式打印
* Basic+ESC+FS
2、 AR命令系列:
* 应用于滚筒方式打印
* Basic+ESC+FS+SUB :ESC,FS与EPSON兼容,SUB为扩展中文打印
3、 IBM命令系列:
* 应用于滚筒方式打印
* Basic+ESC:ESC基本与EPSON兼容
4、 OKI命令系列:
* 应用于平推方式打印
* Basic+ESC+CEX:ESC为自定义系统,CEX为扩展中文打印
5、 PR命令系列:
* 应用于存折和证本的打印
* Basic+ESC+FS:ESC,FS为自定义系统(通用打印控制命令+存折控制+设备控制)

四、ESC/P控制命令分析
ESC/P 控制命令是EPSON公司制定的基本控制命令,它主要适应各种针式打印机和与之兼容的各种喷墨打印机,
并已成为事实上的滚筒针式打印机的应用标准。

1、 特征

1)唯一性:单一功能用单一控制码表示。
2)整体系统发展具有阶段性。
3)高版本完全包容低版本。
4)从一般打印机逐步推广到高端打印机,从针式推广到喷墨、激光打印机
5)与硬件的无关性,只考虑ESC/P版本即可。

2、结构
下图表示了ESC/P各个版本之间相互包含的关系。

3、命令功能分析
ESC/P 命令序列按其功能分类,可分为以下5个方面:

1)打印格式控制
2)英文打印命令
3)中文打印命令
4)图象打印命令
5)打印机控制命令

五、控制命令的输入方法
下面列出在各种程序语言中常用的输入控制命令的方法:

语言名称 函数或语句
BASIC CHR$(X)
FOXbase CHR(X)
C FPRINTF(prn,”%C,X)
PASCAL CHR(X)
FORTRAN CHAR(X)
汇编 MOV AL,X
INT 17H

打印机的控制命令也是根据市场发展和客户更高的需求,而与时俱进,不断发展的。就其技术发展可分为两个方面:控制命令本身的发展和命令应用方面的发展。

在控制命令本身的发展方面,EPSON的ESC PK命令集就是一个非常典型的事例,一方面在本身针打领域,由ESC P、ESC PK、ESC PK2 不断的提升控制和文字处理能力和水平。另一方面,又适时推出ESC Page 使其从针打领域向喷墨、激光打印机领域扩展。

在控制命令应用的发展方面,各生产厂家都在向:一种机型、多种控制命令仿真;的目标发展,以适应不同客户、不同应用的要求。这也是打印机控制命令在应用方面的发展方向。

对于打印机所实现的复杂控制功能而言,打印控制语言是基础。它直接关系到打印控制的实现和输出质量的优劣。因此增强对打印机控制命令的了解和掌握,无论是打印机的开发厂商还是用户,都是至关重要的。

代码 功能 代码 功能
LF 换行 ESC m 局部切割
CR 回车 ESC o 印章
ESC SP 设置右边界 ESC q 释放纸
ESC ! 设置打印方式 ESC r 选择打印颜色
ESC * 设置位映射方式 ESC z 设置或取消两页并行打印
ESC @ 初始化打印机 ESC BEL 蜂鸣器ON/OFF
ESC R 选择国际字符子集 ESC c5 禁止/使能面板开关
ESC d 打印及N行进纸 ESC c6 禁止/使能ON-LINE开关
ESC t 选择字符码表 ESC p 产生指定脉冲
ESC l 选择或取消倒过来的字符ESC V 发送打印机状态
ESC c0 选择打印页 ESC ~ LED ON/OFF
FF 打印送出单页 HT 水平TAB
RS 流水TAB ESC % 选择或取消用户自定义字符集
ESC 2 选择行间距为1/6英寸 ESC & 定义用户自定义字符集
ESC 3 设置行进为最小间距 ESC D 设置TAB位置
ESC < 返回行首 ESC i 全切割
ESC C 设置单页长度 ESC f 设单页等待时间
ESC F 选择或取消单页退纸区 ESC e 打印病退回N行
ESC J 以最小间距进行打印和进纸 ESC c4 选择打印纸及检测器(终止打印)
ESC K 以最小间距进行打印和退纸 ESC c3 选择纸结束信号输出
ESC U 选择或取消单向打印 ESC c1 选择行间距
中文模式下的命令
代码 功能 代码 功能
FS & 选择中文字符模式 FS – n 设置中文字符下划线模式开关
FS . 取消中文模式 FS ! n 选择中文字体

标签: , , ,

星期二, 一月 06, 2009

PortTalk - A Windows NT I/O Port Device Driver

A problem that plagues Windows NT/2000 and Windows XP, is it's strict control over I/O ports. Unlike Windows 95 & 98, Windows NT/2000/XP will cause an exception (Privileged Instruction) if an attempt is made to access a port that you are not privileged to talk too. Actually it's not Windows NT that does this, but any 386 or higher processor running in protected mode.

Accessing I/O Ports in protected mode is governed by two events, The I/O privilege level (IOPL) in the EFLAGS register and the I/O permission bit map of a Task State Segment (TSS).


Under Windows NT, there are only two I/O privilege levels used, level 0 & level 3. Usermode programs will run in privilege level 3, while device drivers and the kernel will run in privilege level 0, commonly referred to as ring 0. This allows the trusted operating system and drivers running in kernel mode to access the ports, while preventing less trusted usermode processes from touching the I/O ports and causing conflicts. All usermode programs should talk to a device driver which arbitrates access.

The I/O permission bitmap can be used to allow programs not privileged enough (I.e. usermode programs) the ability to access the I/O ports. When an I/O instruction is executed, the processor will first check if the task is privileged enough to access the ports. Should this be the case, the I/O instruction will be executed. However if the task is not allowed to do I/O, the processor will then check the I/O permission bitmap.

The I/O permission bitmap, as the name suggests uses a single bit to represent each I/O address. If the bit corresponding to a port is set, then the instruction will generate an exception however if the bit is clear then the I/O operation will proceed. This gives a means to allow certain processes to access certain ports. There is one I/O permission bitmap per task.

http://www.beyondlogic.org/porttalk/

标签: , , ,

星期二, 十二月 30, 2008

[学习]DelphiZeus 9. 菜单和列表框--3

procedure CopyMenuItem;
begin
{这个过程将通过 GetMenuItemInfo 获取菜单项设置并在 menuListB2 最后一个菜单项
复制一次。}
MenuInfo.cbSize := SizeOf(MenuInfo);
MenuInfo.dwTypeData := @CharBuffer[0];
{给 MenuInfo.dwTypeData 赋值一个内存区域}
MenuInfo.cch := 256;
{由于使用 GetMenuItemInfo 获取一个字符串,你需要设置 MenuInfo.cch 。}
MenuInfo.fMask := MIIM_STATE or MIIM_ID or MIIM_TYPE or MIIM_DATA or
MIIM_SUBMENU or MIIM_CHECKMARKS;
{留个标志全部使用,这样不管菜单项是字符串、分隔符、子菜单还是位图,这将得到所有的设置。}
GetMenuItemInfo(menuFile, CopyNum, False, MenuInfo);
{GetMenuItemInfo 将放置所有菜单项的设置到 MenuInfo 里面,包括类型与状态。}
SetMenuItemInfo(menuListB2, 6, True, MenuInfo);
{SetMenuItemInfo 将复制 menuFile 的所有菜单项的设置到 menuListB2 菜单的 MenuInfo 。}
if CopyNum < stresult =" $FFFFFFFF" stresult =" StResult" fstate =" MenuInfo.fState" wparam =" 901" wparam =" 902" lparam =" 0"> 2 then
begin
if CFolder[Length(CFolder)] <> '\' then
CFolder := CFolder + '\';
if DirectoryExists(CFolder) then
begin
GetShortPathName(@Cfolder[1], Buffer, 82);
Cfolder := Buffer + '*.*';
SendMessage(hListBox1, LB_RESETCONTENT, 0, 0);
SendMessage(hListBox1, LB_DIR, DDL_READONLY or DDL_DIRECTORY,
Integer(PChar(CFolder)))
end
else
MessageBox(hForm1, '文件夹不存在', '无文件夹',
MB_OK or MB_ICONERROR);
end;
end;
mID_m2AddSel: SelToLB3(True);
mID_m2Clear: SendMessage(hListBox1, LB_RESETCONTENT, 0, 0);
mID_m2ChangeItem:
begin
{这里使用 SetMenuItemInfo 函数立即改变几个菜单项属性}
MenuInfo.cbSize := SizeOf(MenuInfo);
MenuInfo.fMask := MIIM_STATE;
GetMenuItemInfo(menuListB1, 205, False, MenuInfo);
if MenuInfo.fState = MenuInfo.fState or MFS_CHECKED then
begin
MenuInfo.fMask := MIIM_STATE or MIIM_TYPE;
MenuInfo.fType := MFT_STRING;
MenuInfo.fState := MFS_UNCHECKED;
MenuInfo.dwTypeData := '旧的 菜单项';
end
else
begin
MenuInfo.fMask := MIIM_STATE or MIIM_TYPE;
MenuInfo.fType := MFT_STRING;
MenuInfo.fState := MFS_CHECKED or MFS_GRAYED;
MenuInfo.dwTypeData := '新的 菜单项';
end;
SetMenuItemInfo(menuListB1, 205, False, MenuInfo);
{这里 SetMenuItemInfo 改变菜单项的三个属性:勾选、文本与变灰。}
Returned := GetMenuDefaultItem(menuListB1, 0, 0);
{如果没有默认菜单项则返回 4294967295 = $FFFFFFFF}
SetWindowText(hEdit1, PChar(Int2Str(Returned)));
end;
mID_m2Item: DoMessage;
{上面的所有菜单项 ID 使用常量名代替了。下面会直接使用菜单项的 ID 编号,
这样知道 ID 代表哪个菜单和哪个菜单项比较困难,这里使用百位数(301,401,
501)来表示不同的子菜单,但是你需要参照菜单创建部分了解数字(如 302)
表示哪个菜单项。使用菜单项 ID 的常量是比较好的做法,采用命名约定如
mID_m1New、mID_m2NewFolder,m1 和 m2 分辨表示子菜单1 和子菜单2 。}
301:
begin
CFolder := GetWindowStr(hEdit1);
if Length(CFolder) > 2 then
begin
if CFolder[Length(CFolder)] <> '\' then
CFolder := CFolder + '\';
if DirectoryExists(CFolder) then
GetFiles(Cfolder)
else
MessageBox(hForm1, '文件夹不存在', '无文件夹',
MB_OK or MB_ICONERROR);
end;
end;
302: SelToLB3(False);
303: SendMessage(hListBox2, LB_RESETCONTENT, 0, 0);
304: CopyMenuItem;
401..402: SortListBox;
403: SendMessage(hListBox3, LB_RESETCONTENT, 0, 0);
404: if MenuCheck(3, 4) = 0 then
SetWindowText(hEdit1, 'It was Checked');
405:
begin
RemoveMenu(MenuMain, 3, MF_BYPOSITION);
{RemoveMenu 将移除菜单项但是不销毁子菜单}
EnableMenuItem(menuFile, mID_m1Show, MF_BYCOMMAND or MF_ENABLED);
{"文件"菜单的"显示菜单"菜单项将可用}
DrawMenuBar(hForm1);
{DrawMenuBar 将重绘主菜单来显示变化}
end;
501: DoMessage;
502: MoveWindow(hWnd, 1, 1, Rect1.Right - Rect1.Left, Rect1.Bottom -
Rect1.Top, True);
503: MessageBox(hForm1, About, '关于', MB_OK or
MB_ICONINFORMATION);
504: PostMessage(hForm1, WM_CLOSE, 0, 0);
701..765:
begin
{ID 编号 701 到 765 是在 menuSubFolder1 中为 C 盘文件夹准备}
GetMenuStr(True);
Cfolder := 'C:\' + MenuInfo.dwTypeData;
GetShortPathName(@Cfolder[1], Buffer, 82);
Cfolder := Buffer + '\*.*';
if MessageBox(hForm1,
PChar('你希望显示'+ MenuInfo.dwTypeData + ' 内的文件和文件夹? ?'),
MenuInfo.dwTypeData, MB_YESNO or MB_ICONQUESTION) = IDYES then
begin
SendMessage(hListBox1, LB_RESETCONTENT, 0, 0);
SendMessage(hListBox1, LB_DIR, DDL_READONLY or DDL_DIRECTORY,
Integer(@Cfolder[1]));
end;
end;
801..865:
begin
{ID 编号 801 到 865 是在 menuSubFolder2 中为 C 盘文件夹准备}
GetMenuStr(False);
Cfolder := 'C:\' + MenuInfo.dwTypeData + '\';
DlgChk := True;
GetFiles(Cfolder);
end;
end; // case LOWORD(wParam)
end;
WM_INITMENUPOPUP: if wParam = menuSubFolder2 then
begin
{在子菜单显示前会发送 WM_INITMENUPOPUP 消息,你可以修改这个子菜单使之
在显示前符合要求。}
SetSubMenu(wParam);
end
else if wParam = hSysMenu then
SetWindowText(hEdit1, PChar('系统菜单 lParam 为 ' + Int2Str(lParam)));
WM_CTLCOLORLISTBOX: if lParam = hListBox3 then
begin
{WM_CTLCOLORLISTBOX 获取列表框使用的颜色}
SetTextColor(wParam, $0000FF);
SetBkColor(wParam, $FFFF00);
Result := GetStockObject(LTGRAY_BRUSH);
Exit;
end;
WM_DESTROY: ShutDown;
end; // case Msg
Result := DefWindowProc(hWnd, Msg, wParam, lParam);
end;

begin // * * * * * * * 主程序开始
CopyNum := mID_m1New;
wClass.hInstance := hInstance;
with wClass do
begin
Style := 0;
hIcon := LoadIcon(hInstance, 'MAINICON');
lpfnWndProc := @MessageFunc;
hbrBackground := COLOR_BTNFACE + 1;
lpszClassName := 'Text Class';
hCursor := LoadCursor(0, IDC_ARROW);
cbClsExtra := 0;
cbWndExtra := 0;
lpszMenuName := nil;
end;
RegisterClass(wClass);
{这里将在创建主菜单之前创建菜单栏的子菜单,因为它们必须被加入主菜单。第一个子
菜单为"文件"菜单,但是本程序不涉及任何文件操作,因此这个子菜单仅仅用于演示。}
menuFile := CreateMenu;
{CreateMenu 函数将创建一个空菜单,在使用前必须加入菜单项。这里使用了三个函数
添加菜单项:AppendMenu、 InsertMenu 和 InsertMenuItem 。}
{这个 menuFile 菜单将使用 AppendMenu 添加菜单项,它有四个参数。第三个参数
uIDNewItem 是 ID 编号,它将在菜单单击时通过 WM_COMMAND 消息的 LOWORD(wParam)
发送。AppendMenu 按照调用次序顺次添加菜单项,类似于 Delphi 的"Add" 过程。}
AppendMenu(menuFile, MF_STRING, mID_m1New, '&N新建');
AppendMenu(menuFile, MF_STRING or MF_GRAYED, mID_m1Open, '&O打开');
AppendMenu(menuFile, MF_STRING or MF_CHECKED, mID_m1Save, '&S保存');
{MF_CHECKED 将会勾选菜单项}
AppendMenu(menuFile, MF_STRING, mID_m1SaveAs, '另存为(&A)');
AppendMenu(menuFile, MF_STRING or MF_GRAYED, mID_m1Show, '显示菜单');
AppendMenu(menuFile, MF_SEPARATOR, 1, nil);
{MF_SEPARATOR 将在菜单中添加分隔线,后两个参数不使用}
AppendMenu(menuFile, MF_STRING, mID_m1Exit, 'E&退出');
{MF_STRING 参数将会添加文本菜单项,MF_BITMAP 参数将会添加位图,MF_OWNERDRAW
将会指定一个自定义绘制的菜单项。}
EnableMenuItem(menuFile, mID_m1New, MF_GRAYED);
{这里使用 EnableMenuItem 使"新建"菜单项变灰并禁用它,"打开"菜单也会变灰,因为
它使用了 MF_GRAYED 参数。}
SetMenuDefaultItem(menuFile, mID_m1Exit, 0);
{SetMenuDefaultItem 将会使默认菜单项变粗显示,在双击菜单时会执行此默认菜单项。}
menuSubFolder1 := CreateMenu();
{menuSubFolder1 是在后面创建的 menuListB1 的子菜单。这个 menuSubFolder1 将会
在程序运行时列出 C:\ 盘的所有文件夹。}
SetSubMenu(menuSubFolder1);
{SetSubMenu 只在创建永不更新的 menuSubFolder1 过程中使用,menuSubFolder2 则是
每次子菜单显示的时候都更新。}
menuListB1 := CreateMenu;
{menuListB1 将使用 AppendMenu 添加菜单项。另一个菜单项将在最后使用 InsertMenu
不按照前面的次序添加。}
AppendMenu(menuListB1, MF_STRING, mID_m2NewFolder, '&N编辑框指定的新文件夹');
AppendMenu(menuListB1, MF_STRING, mID_m2AddSel, '加入所选项列表框3 ');
AppendMenu(menuListB1, MF_STRING, mID_m2Clear, '清空');
AppendMenu(menuListB1, MF_SEPARATOR, 1, nil);
AppendMenu(menuListB1, MF_STRING, mID_m2ChangeItem, '改变 菜单项');
AppendMenu(menuListB1, MF_STRING, mID_m2Item, '菜单项');
{下面的 InsertMenu( ) 将在菜单的第二个位置放置一个子菜单项。uPosition 为 1,
如果 Count 大于 0,你不能为空的菜单项添加子菜单。}
if Count > 0 then
InsertMenu(menuListB1, 1, MF_BYPOSITION or MF_POPUP or MF_STRING,
menuSubFolder1, 'C 盘文件夹');
{使用 MF_POPUP 标志在 menuListB1 添加一个子菜单,句柄在第四个参数。}
menuSubFolder2 := CreateMenu();
{这里创建的 menuSubFolder2 只有一个菜单项,菜单项将会在菜单显示使用目录填充,
参见上面的 WM_INITMENUPOPUP 消息部分。}
AppendMenu(menuSubFolder2, MF_STRING, 799, ' ');
{子菜单必须有一个菜单项,才能成功加入到另一个菜单的菜单项。}
menuListB2 := CreateMenu;
{利用 TMenuItemInfo 记录,使用功能强大的 InsertMenuItem() 函数,菜单项将被
加入到这个 menuListB2 菜单。}
MenuInfo.cbSize := SizeOf(MenuInfo);
{在使用 TMenuItemInfo 前注意设置 cbSize }
MenuInfo.fMask := MIIM_ID or MIIM_TYPE;
{第一个菜单项是标准的字符串菜单项,ID 编号为 301 ,因此你需要设置
MIIM_ID or MIIM_标志。}
MenuInfo.fType := MFT_STRING;
{设置 MFT_STRING 标志为菜单项放入字符串}
MenuInfo.dwTypeData := '&N编辑框指定的新文件夹';
//MenuInfo.cch := 21;
{如果 fType 标志设置为 MFT_STRING ,那么 dwTypeData 将被读取为 PChar 字符串,
你不必设置 MenuInfo.cch 为字符串长度,因为它不会从 MenuInfo.cch 读取数据。cch
将在写入字符并且不会读入 dwTypeData 时使用。}
MenuInfo.wID := 301;
{如果设置 MIIM_ID 标志,那么 wID 会被作为 ID 编号使用。注意这里是 wID,暗示这
是 WORD 类型,最大值为 65534。}
//MenuInfo.fState := 0;
//MenuInfo.hSubMenu := 0;
//MenuInfo.hbmpChecked := 0;
//MenuInfo.hbmpUnchecked := 0;
{不需要设置 MenuInfo 的其他域成员因为它们会被忽略}
InsertMenuItem(menuListB2, 0, False, MenuInfo);
{如果第三个参数设置为 False 那么第二个参数被作为 ID 使用,但是如果设置第二个
参数为 0,它就像 AppendMenu( ) 函数一样使用,将会把菜单项加入到最后位置。}
MenuInfo.fMask := MIIM_SUBMENU or MIIM_TYPE;
MenuInfo.fType := MFT_STRING;
MenuInfo.dwTypeData := 'C 盘文件夹';
MenuInfo.hSubMenu := menuSubFolder2;
InsertMenuItem(menuListB2, 1, False, MenuInfo);
MenuInfo.fMask := MIIM_ID or MIIM_TYPE;
MenuInfo.fType := MFT_STRING;
MenuInfo.dwTypeData := '加入所选项列表框3 ';
MenuInfo.wID := 302;
InsertMenuItem(menuListB2, 2, False, MenuInfo);
{如果第三个参数设置为 True 那么第二个参数被作为菜单项位置使用,
类似于 InsertMenu( ) 函数。}
MenuInfo.fMask := MIIM_ID or MIIM_TYPE;
MenuInfo.fType := MFT_STRING;
MenuInfo.dwTypeData := '清空';
MenuInfo.wID := 303;
InsertMenuItem(menuListB2, 3, False, MenuInfo);
MenuInfo.fMask := MIIM_TYPE;
MenuInfo.fType := MFT_SEPARATOR;
{使用 MFT_SEPARATOR 则不需要其他成员}
InsertMenuItem(menuListB2, 4, True, MenuInfo);
MenuInfo.fMask := MIIM_ID or MIIM_TYPE;
MenuInfo.fType := MFT_STRING;
MenuInfo.dwTypeData := '复制 菜单项';
MenuInfo.wID := 304;
InsertMenuItem(menuListB2, 5, True, MenuInfo);
MenuInfo.fMask := MIIM_ID or MIIM_TYPE;
MenuInfo.fType := MFT_STRING;
MenuInfo.dwTypeData := '尚未复制';
MenuInfo.wID := 305;
InsertMenuItem(menuListB2, 6, True, MenuInfo);
TempDC := GetDC(0);
BmpDC := CreateCompatibleDC(TempDC);
{准备在 menuListB3 菜单使用位图菜单项,这里创建位图并在上面标注"清空"。}
Bitmap1 := CreateCompatibleBitmap(TempDC, 39, 18);
SelectObject(BmpDC, Bitmap1);
SetRect(Rect1, 0, 0, 39, 18);
FillRect(BmpDC, Rect1, GetStockObject(BLACK_BRUSH));
SelectObject(BmpDC, GetStockObject(WHITE_BRUSH));
SetBkColor(BmpDC, $FFFFFF);
Ellipse(BmpDC, 0, 0, 39, 18);
SelectObject(BmpDC, GetStockObject(ANSI_VAR_FONT));
SetTextColor(BmpDC, $000000FF);
TextOut(BmpDC, 7, 2, '清空', 5);
DeleteDC(BmpDC);
ReleaseDC(0, TempDC);

menuListB3 := CreateMenu;
AppendMenu(menuListB3, MF_STRING, 401, '&S排序');
AppendMenu(menuListB3, MF_STRING, 402, '允许拖放');
AppendMenu(menuListB3, MF_BITMAP, 403, PChar(Bitmap1));
{使用 MF_BITMAP 需要把 Bitmap 句柄强制转化为 PChar}
AppendMenu(menuListB3, MF_SEPARATOR, 1, nil);
AppendMenu(menuListB3, MF_STRING, 404, '勾选');
AppendMenu(menuListB3, MF_STRING, 405, '隐藏此菜单');
CheckMenuRadioItem(menuListB3, 0, 1, 1, MF_BYPOSITION);
{CheckMenuRadioItem 将会设置一组菜单项为单选按钮风格,这组菜单项只有一个能被
用圆点形式选中。这里放置菜单项第 0 和 1 位置到分组中。}
CanDrag := True;
menuMain := CreateMenu;
{这里创建了主菜单}
{TMenuItemInfo 记录包含所有需要创建的菜单项的信息,这里还有比 AppendMenu 更
丰富的可用选项。}
MenuInfo.fMask := MIIM_SUBMENU or MIIM_TYPE;
{fMask 域你需要设置标志告知系统产生什么样的菜单属性}
MenuInfo.fType := MFT_STRING;
MenuInfo.dwTypeData := '&F文件';
MenuInfo.hSubMenu := menuFile;
InsertMenuItem(menuMain, 0, True, MenuInfo);
MenuInfo.dwTypeData := '列表框&1';
MenuInfo.hSubMenu := menuListB1;
InsertMenuItem(menuMain, 1, True, MenuInfo);
MenuInfo.dwTypeData := '列表框&2';
MenuInfo.hSubMenu := menuListB2;
InsertMenuItem(menuMain, 2, True, MenuInfo);
MenuInfo.dwTypeData := '列表框&3';
MenuInfo.hSubMenu := menuListB3;
InsertMenuItem(menuMain, 3, True, MenuInfo);
SetRect(Rect1, 0, 0, 536, 321);
if not AdjustWindowRect(Rect1, WS_CAPTION or WS_MINIMIZEBOX or WS_SYSMENU,False) then
SetRect(Rect1, 0, 0, 542, 347);

hForm1 := CreateWindow(wClass.lpszClassName, '菜单与列表框',
WS_CAPTION or WS_MINIMIZEBOX or WS_SYSMENU,
(GetSystemMetrics(SM_CXSCREEN) div 2) - 276,
(GetSystemMetrics(SM_CYSCREEN)div 2) - 212,
Rect1.Right - Rect1.Left, Rect1.Bottom - Rect1.Top, 0,
menuMain, // handle to main menu
hInstance, nil);
{SendMessage(CreateWindow('Static', '菜单与列表框',
WS_VISIBLE or WS_CHILD, 6, 3, 300, 20, hForm1, 0, hInstance, nil),
WM_SETFONT,GetStockObject(ANSI_VAR_FONT),0);}

{通过 WS_EX_CLIENTEDGE 风格 CreateWindowEx( ) 可以获取这些列表框的 3D 风格外观,
使用 LBS_HASSTRINGS or LBS_NOTIFY 标志在列表框使用字符串并通知父窗体消息。}
hListBox1 := CreateWindowEx(WS_EX_CLIENTEDGE, 'LISTBOX', 'C:\',
WS_VISIBLE or WS_CHILD or LBS_HASSTRINGS or LBS_NOTIFY or WS_VSCROLL,
8, 30, 150, 220, hForm1, 101, hInstance, nil);
SendMessage(hListBox1, WM_SETFONT, GetStockObject(ANSI_VAR_FONT), 0);
SendMessage(hListBox1, LB_DIR, DDL_READONLY or DDL_DIRECTORY,
Integer(PChar('C:\*.*')));
{这里使用发送 LB_DIR 消息的老办法在列表框1 中列出文件夹项,它以短文件名形式
显示,LB_DIR 主要针对过时的 Windows 3.x ,对于显示 32 位的长文件名的程序则
没有太大用处。}

PListbox1Proc := Pointer(SetWindowLong(hListBox1, GWL_WNDPROC,
Integer(@Listbox1Proc)));
{列表框1 和列表框3 被子类化,所以可以通过处理它们的消息进行很多操作。}

hListBox2 := CreateWindowEx(WS_EX_CLIENTEDGE, 'LISTBOX', nil,
WS_VISIBLE or WS_CHILD or LBS_HASSTRINGS or LBS_NOTIFY or WS_VSCROLL,
168, 30, 160, 220, hForm1, 0, hInstance, nil);
SendMessage(hListBox2, WM_SETFONT, GetStockObject(ANSI_VAR_FONT), 0);

hListBox3 := CreateWindowEx(WS_EX_CLIENTEDGE, 'LISTBOX',
'ListBox 3 selected is ',
WS_VISIBLE or WS_CHILD or LBS_HASSTRINGS or LBS_NOTIFY or WS_VSCROLL,
338, 30, 188, 220, hForm1, 0, hInstance, nil);
SendMessage(hListBox3, WM_SETFONT, GetStockObject(ANSI_FIXED_FONT), 0);
SendMessage(hListBox3, LB_INSERTSTRING, 0, Integer(PChar('列表框 3')));
{使用 LB_INSERTSTRING 添加文本到一个列表框,你需要强制转化 LParam 为 PChar,
再转化为 Integer 类型。}
PListbox3Proc := Pointer(SetWindowLong(hListBox3, GWL_WNDPROC,
Integer(@Listbox1Proc)));
{列表框1 和列表框3的子类化函数都设置为 Listbox1Proc ,这样一个列表框函数就
可以处理这两个列表框的消息。}

hEdit1 := CreateWindowEx(WS_EX_CLIENTEDGE, 'Edit', 'Wacky',
WS_VISIBLE or WS_CHILD or ES_LEFT or ES_AUTOHSCROLL,
16, 272, 400, 21, hForm1, 0, hInstance, nil);
SendMessage(hEdit1, WM_SETFONT, GetStockObject(ANSI_VAR_FONT), 0);

if PListbox1Proc = PListbox3Proc then
SetWindowText(hEdit1, 'C:\WINDOWS');
{如果你测试 - if PListbox1Proc = PListbox3Proc - 它是相等的,因为系统只有
一个列表框消息处理过程,它区分不同的列表框的不同设置是通过发送给系统的消息
处理过程的列表框句柄来实现的。}

DlgChk := True;
GetFiles('C:\');
{和列表框1 不一样,在列表框2 中我们使用 GetFiles 中的 FindFirstFile,这样可以
获取长文件名和文件列表,这样你可以更好控制列出的文件。}
ShowWindow(hForm1, SW_SHOWDEFAULT);
{GetSystemMenu( ) 将会获取系统菜单句柄,你可以利用菜单相关 API 函数处理系统菜单。}
hSysMenu := GetSystemMenu(hForm1, False);
InsertMenu(hSysMenu, 0, MF_BYPOSITION or MF_STRING, 901, 'Added Item');
InsertMenu(hSysMenu, 4, MF_BYPOSITION or MF_STRING, 902, 'MOVE WINDOW');
{两个菜单项被加入系统菜单}

while GetMessage(MainMsg, 0, 0, 0) do
begin
TranslateMessage(MainMsg);
DispatchMessage(MainMsg);
end;
DlgEditText := '';
{由于 menuListB3 可以被移除,所以记得销毁它。一旦某个子菜单被移除,它就没有
Owner 来自动销毁。}
DestroyMenu(menuListB3);
end.

来源:http://blog.tom.com/jdzmc_wanqing/article/1632.html

标签: , ,

星期一, 十二月 29, 2008

vnc2swf Screen Recorder

Vnc2swf is a cross-platform screen recording tool for ShockWave Flash (swf) or Flash Video (flv) format.


http://davidf.sjsoft.com/files/pyvnc2swf/

标签: , , , ,

星期三, 十二月 24, 2008

怎么在注册表里修改屏幕的分辨率

参考:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\SERVICES\IALM\DEVICE0]
"DefaultSettings.XResolution"=dword:00000500
"DefaultSettings.YResolution"=dword:00000400
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\SERVICES\IALM\DEVICE0\Mon80861100]
"DefaultSettings.XResolution"=dword:00000500
"DefaultSettings.YResolution"=dword:00000400

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\0001\System\CurrentControlSet\SERVICES\IALM\DEVICE0]
"DefaultSettings.XResolution"=dword:00000500
"DefaultSettings.YResolution"=dword:00000400
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Hardware Profiles\0001\System\CurrentControlSet\SERVICES\IALM\DEVICE0\Mon80861100]
"DefaultSettings.XResolution"=dword:00000500
"DefaultSettings.YResolution"=dword:00000400

[HKEY_CURRENT_CONFIG\System\CurrentControlSet\SERVICES\IALM\DEVICE0]
"DefaultSettings.XResolution"=dword:00000500
"DefaultSettings.YResolution"=dword:00000400
[HKEY_CURRENT_CONFIG\System\CurrentControlSet\SERVICES\IALM\DEVICE0\Mon80861100]
"DefaultSettings.XResolution"=dword:00000500
"DefaultSettings.YResolution"=dword:00000400

标签:

星期三, 十月 29, 2008

VIDE

VIDE is the V Integrated Development Environment for the GNU g++ compiler and the standard Sun Java Development Kit. The current release is Version 2.00 for MS-Windows and Linux (RedHat 6.x, 7.x, 8.x; Mandrake 8.x; others).
http://www.objectcentral.com/objectcentral/vide.htm

标签: , , , , ,

BVRDE - 远程C++开发环境

BVRDE is an Integrated Development Environment (IDE) for C and C++. It is designed to make cross-platform development easy. Its features include project management, application wizards, an integrated interactive debugger, and a powerful source editor with source browsing and syntax highlighting.

The goal of this tool is to allow a developer to compile and debug applications entirely on a remote computer, while editing and issuing compile and debug commands through a local interface. BVRDE supports a variety of network protocols to allow connectivity with various remote systems. This includes FTP and secure & encrypted protocols such as SSH and SFTP.

http://bvrde.sourceforge.net/

标签: , , , , ,

星期二, 十月 21, 2008

EXE图标替换

杂志文章作者:牵着蜗牛去散步

HINSTANCE hInstance=LoadLibrary("D:\\dd.exe");//载入图标源文件 5~8FZ-x
HRSRC hRsrc = FindResource(hInstance,(LPCSTR)1,(LPCSTR)RT_ICON); //查找源文件中的图标文件 -!_\4
LPVOID lpRes = LockResource(LoadResource(hInstance,hRsrc)); //锁定资源 GTYCNi66
HANDLE hUpdateRes = BeginUpdateResource("D:\\dd2.exe", FALSE); //更新dd2文件图标为dd的 *aem5 E`c
UpdateResource(hUpdateRes,(LPCSTR)RT_ICON, (LPCSTR)1,0,lpRes,SizeofResource(hInstance,hRsrc)); //更新图标资源 }253Q!f
EndUpdateResource(hUpdateRes,FALSE); //结束更新资源 WF#3'"I
CloseHandle(hRsrc); //关闭句柄 y"bSn5B[
CloseHandle(hUpdateRes);//关闭句柄 l(�Y U9dp
FreeLibrary(hInstance); //释放载入的源文件 85{2TXQ^%=

http://www.nn4a.com/bbs/read.php?tid=9818

再来一段Delphi写的:

给你一段读写自身icon的程序。写别的程序的,只需要loadlibrary,用它的句柄代替hinstance.

PCursorOrIcon = ^TCursorOrIcon;
TCursorOrIcon = packed record
Reserved: Word;
wType: Word;
Count: Word;
end;
//This has been defined in DELPHI9. But not the definition of IconEntry.
PIconEntry = ^TIconEntry;
TIconEntry= packed record
bWidth : Byte; // Width, in pixels, of the image
bHeight : Byte; // Height, in pixels, of the image
bColorCount: Byte; // Number of colors in image (0 if >=8bpp)
bReserved: Byte; // Reserved ( must be 0)
wPlanes : word; // Color Planes
wBitCount : word; // Bits per pixel
dwBytesInRes : dword; // How many bytes in this resource?
dwImageOffset : dword;
end;

var
hRes,hMem:HRSRC;
lpMem : Pointer;
lp1 : PBYTE;
n : integer;
ts : TMemoryStream;
IconHeader : TCursorOrIcon;
IconEntry : TIconEntry;

begin
ts:=TMemoryStream.Create;
hRes:=FindResource(hInstance,'small',rt_group_icon);
hMem:=LoadResource(hInstance,hRes);
lpMem:=LockResource(hMem);
IconHeader.Reserved:=PWord(lpMem)^; //usually be $0.
IconHeader.wType:=$01; //$01 for ICON
IconHeader.Count:=$01; // we just want lookup a single icon.
//ts.Write(pbyte(lpMem)^,sizeof(TCursorOrIcon));
ts.Write(IconHeader,sizeof(IconHeader));

n := LookUpIconIDFromDirectoryEx(PBYTE(lpMem),True,16,SM_CYSMICON,LR_DEFAULTCOLOR);
hRes:=FindResource(hInstance,MakeIntResource(n),rt_icon);
hMem:=LoadResource(hInstance,hRes);
lpMem:=LockResource(hMem);

IconEntry.bWidth:= TBitmapInfoHeader(lpMem^).biWidth;
IconEntry.bHeight:=TBitmapInfoHeader(lpMem^).biHeight div 2;
n:=TBitmapInfoHeader(lpMem^).biPlanes * TBitmapInfoHeader(lpMem^).biBitCount;
if n>=8 then IconEntry.bColorCount:=0
else IconEntry.bColorCount:= 1 shl n;

IconEntry.bReserved:=$0;
IconEntry.wBitCount:=TBitmapInfoHeader(lpMem^).biBitCount;
IconEntry.wPlanes:=TBitmapInfoHeader(lpMem^).biPlanes;
IconEntry.dwBytesInRes:= sizeofResource(hInstance,hRes);
IconEntry.dwImageOffset:=sizeof(TCursorOrIcon)+sizeof(TIconEntry);

ts.Write(IconEntry,sizeof(IconEntry));
ts.Write(pbyte(lpMem)^,IconEntry.dwBytesInRes);
ts.SaveToFile('test.ico');
ts.Free;
end;

http://zhidao.baidu.com/question/33643445.html

还有:http://www.180it.com/read.php?32

标签: , , ,

星期三, 九月 24, 2008

Multiple Thread Progress Bar Control

Introduction

This article presents a control that creates threads and displays the progress and any messages sent from the thread.

Background

Running multiple threads and seeing the status of where they are has been a tricky subject for quite a while. The main thing being that you could not access anything that is being controlled by the main (UI) thread. This includes all parts of the form you are displaying and the properties and variables on it.

The .Net framework 2.0 has helped clear up some of that with the introduction of the BackgroundWorker class. This class allows you to run some code on its own thread. This allows your UI to remain responsive while the code runs.

What It Does

This control can be easily modified to be used to monitor/control batch operations that can be done simultaneously. Some examples:

  • File Transfers
  • Image Processing
  • Directory Processing
  • Screen scraping

Each thread can send its own messages back to the container. The container shows those messages in a grid as the threads are running.

The thread container actually does throttling as well. Before you start the threads, you can set the number of threads you want to run concurrently. I hope to eventually make this property dynamic so that it can be changed on the fly.

What It Does Not Do

This control is designed for items that do not update the UI other than what is already displayed. If you need to render objects and update the screen, you will need to modify the way this works. That may be another article.

How it Works

Each thread is represented in a ThreadView which inherits from UserControl. This ThreadView contains a BackgroundWorker. When the ThreadContainer.Start method is called it creates as many threads as it can (either Concurrent or TotalThreads if it is less than Concurrent). The ThreadViews are docked to the top so that they are all displayed nicely and expand to the width of the ThreadContainer. After creating the new ThreadView and displays it and starts it. As it works it raises its JobEvent event. This passes the message to the container and the ThreadContainer stores it in its DataTable.

Each ThreadView contains a JobCompleted event that notifies the ThreadContainer that it is done.

http://www.codeproject.com/KB/progress/MultiThreadProgressBar.aspx

标签: , , ,

星期三, 九月 10, 2008

GnuWin32

 GnuWin32 provides ports of tools with a GNU or similar open source license, to MS-Windows (Microsoft Windows 95 / 98 / ME / NT / 2000 / XP / 2003 / Vista / 2008)
http://gnuwin32.sourceforge.net/

标签: , ,

Gawk for Windows

Description

Several kinds of tasks occur repeatedly when working with text files. You might want to extract certain lines and discard the rest. Or you may need to make changes wherever certain patterns appear, but leave the rest of the file alone. Writing single-use programs for these tasks in languages such as C, C++ or Pascal is time-consuming and inconvenient. Such jobs are often easier with awk. The awk utility interprets a special-purpose programming language that makes it easy to handle simple data-reformatting jobs. The GNU implementation of awk is called gawk; it is fully compatible with the System V Release 4 version of awk. gawk is also compatible with the POSIX specification of the awk language. This means that all properly written awk programs should work with gawk. Thus, we usually don’t distinguish between gawk and other awk implementations. Using awk allows you to:

  • Manage small, personal databases
  • Generate reports
  • Validate data
  • Produce indexes and perform other document preparation tasks
  • Experiment with algorithms that you can adapt later to other computer languages.

In addition, gawk provides facilities that make it easy to:

  • Extract bits and pieces of data for processing
  • Sort data
  • Perform simple network communications.

The Win32 port has some limitations, In particular the ‘|&’ operator and TCP/IP networking are not supported.

http://gnuwin32.sourceforge.net/packages/gawk.htm

标签: ,

星期一, 九月 08, 2008

Usage: SetProcessAffinityMask

  1. HANDLE hProcess = GetCurrentProcess();
  2. DWORD dwProcessAffinityMask, dwSystemAffinityMask;
  3. GetProcessAffinityMask( hProcess, &dwProcessAffinityMask, &dwSystemAffinityMask );
  4. // 取得 process Affinity mask
  5. SetProcessAffinityMask( hProcess, 1L );// 執行於 CPU 0
  6. SetProcessAffinityMask( hProcess, 2L );// 執行於 CPU 1
  7. SetProcessAffinityMask( hProcess, 3L );// 允許執行與CPU 0 與 CPU 1 (32bit mask)

标签: ,

星期六, 四月 26, 2008

22项Windows或Mac不能而Linux可以的事

1. Upgrade to the newest version legally and without paying money
1。合法升级到最新版本却不花一分钱
2. Have the latest version of the operating system run faster than the previous version on the same hardware
2。同一个硬件平台上最新的操作系统却比老的更快。

3. Easily install and run different graphical interfaces if I don't like the default setup
3。如果你不喜欢默认的桌面环境,可以非常容易的自行安装其他的界面。
4. Install twenty programs with one command
4。一个命令就可以安装二十个程序。 5. Have the system automatically update all my installed programs for me.
5。让系统自动为我所安装的软件更新。
6. Install the same copy of my OS (Ubuntu) on multiple computers without worrying about license restrictions or activation keys
6。可以在N台机器上安装同一份OS拷贝而无须担心协议限制或激活码。
7. Give away copies of the operating system and other programs that run on it without breaking any laws, governmental or ethical or moral, because it was all intended to be used this way
7。可以自由分发该操作系统及其他运行其上的软件而不会违犯法律,政治或伦理道德,因为他本身就提倡这么做的。
8. Have full control over my computer hardware and know that there are no secret back doors in my software, put there by malicious software companies or governments
8。完全控制我的电脑硬件,并可知晓我的软件中没有什么被政府或者某某公司蓄意安放的秘密后门。
9. Run without using a virus scanner, adware/spyware protection, and not reboot my computer for months, even when I do keep up with all of the latest security updates
9。可以裸奔(无杀毒软件,反广告/间谍防护软件),以及可以数月不用重启机器,我甚至一直在更新着安全补丁。
10. Run my computer without needing to defragment my hard drive, ever
10。从来不用磁盘碎片整理。
11. Try out software, decide I don't like it, uninstall it, and know that it didn't leave little bits of stuff in a registry that can build up and slow down my machine
11。尝试软件,觉得不喜欢,就删掉他,而且知道他不会在什么注册表里留下一些垃圾可能导致把我的系统搞慢。
12. Make a major mistake that requires a complete reinstallation and be able to do it in less than an hour, because I put all of my data on a separate partition from the operating system and program files
12。犯了重大错误而导致全新重装系统,也不过花去了1小时不到的时间,因为我把我的数据放在了独立于操作系统和程序的分区。
13. Boot into a desktop with flash and effects as cool as Windows Vista on a three year old computer...in less than 40 seconds, including the time it takes me to type my username and password to login
13。在一台3岁的老电脑上可以有如vista那样超酷的登录效果...少于40秒,这已经是将我输入用户名和密码并登录计算在内了。
14. Customize anything I want, legally, including my favorite programs. I can even track down the software developers to ask them questions, contribute ideas, and get involved in the actual design/software writing process if I want to
14。合法自定义任何我想要的东西,包括我最喜爱的程序。我甚至可以跟踪软件开发者并向他们问问题,提意见,如果我愿意的话,也可以参与到真正的软件设计和开发进程中去。
15. Have 4+ word processor windows open working on papers, listen to music, play with flashy desktop effects, have contact with a largely happy community and have firefox, instant messaging, and email clients all open at the same time, without ever having had to beg someone for a code to make my os work, and without the system running so slow it is useless
15。超过4个的文字处理窗口,听音乐,玩超酷的桌面效果,联系一个大型的社区,并同时运行着firefox,即时通讯以及email客户端,而不必求爷爷告奶奶的要什么令我的系统可以运作的代码,而不会把系统变慢。
16. Use the command "dpkg --get-selections > pkg.list" to make a full, detailed list of all software I have installed, backup my /etc and /home directories on a separate partition, and you are able to recover your system any time, easily
16。使用"dpkg --get-selections > pkg.list"命令来获得一个完整详尽的已装软件列表,备份我的/etc和/home文件夹到一个独立分区,然后你就可以随时恢复你的系统了,而且超简单。
17. Run multiple desktops simultaneously, or even allow multiple users to log in and use the computer simultaneously
17。同时运行多个桌面,甚至可以让多用户同时登录并使用该机器。
18. Resize a hard disk partition without having to delete it and without losing the data on it
18。无损调整分区大小而不用担心会丢失数据。(译者注:应该是LVM)
19. Use the same hardware for more than 5 years before it really needs to be replaced...I have some hardware that is nearly 10 years old, running Linux, and still useful
19。硬件可以使用超过五年而无须更换...我甚至有一些硬件都超过10年的历史了,还依然健在。
20. Browse the web while the OS is being installed!
20。可以在OS安装的同时浏览网页!
21. Use almost any hardware and have a driver for it included with the operating system...eliminating the need to scour the internet to find the hardware manufacturer's website to locate one
21。使用几乎所有的硬件,因为系统已经自带了驱动...而不必再去硬件供应商的主页上去苦苦搜寻。
22. Get the source code for almost anything, including the OS kernel and most of my applications
22。可以任意获得源代码,包括OS内核以及我的大多数应用程序。

http://linux.chinaunix.net/news/2008/04/25/995585.shtml

标签: , ,

Ubuntu新版Linux免费下载血战Novell

Ubuntu Server 8.04将从本周四开始让用户免费下载。这将使Canonical的Ubuntu与Red Hat Enterprise和Novell平Suse Linux Enterprise更激烈地争夺企业市场。

Ubuntu Server 8.04的支持周期为5年。它能够在Sun的服务器上运行,其中包括Sun Fire X2100 M2、X2200 M2、Sun Fire X4150。Sun负责开放源代码软件业务的经理乔治表示,Ubuntu Server 8.04面向企业市场。

Canonical首席执行官马克表示,Ubuntu Server 8.04一直面临稳定性问题困扰,我们通过更多测试提高了其可靠性。他在接受采访时说,我们将每二年推出一个新的版本。

马克表示,Sun的认证包括1、2、4路x86服务器,Ubuntu没有针对4路以上的系统对Ubuntu Server 8.04进行优化。另外,Canonical还在与惠普、IBM、戴尔就认证问题进行接触。

Ubuntu 8.04中包含Windows整合功能。通过使用第三方厂商Likewise的Likewise Enterprise产品,Ubuntu

8.04能够使用微软活动目录用户身份管理系统的服务。马克说,与Windows网络的整合非常重要。

Ubuntu 8.04还整合有Open JDK,这意味着Ubuntu首次整合了Java虚拟机,能够运行Java应用程序。另外,它还包含有开放源代码版Alfresco内容管理软件、 Bacula网络备份软件、Parallels虚拟软件、Tresys安全软件、PHP、Zimbra电子邮件。

http://linux.chinaunix.net/news/2008/04/23/994703.shtml

标签: , , , ,

星期二, 四月 22, 2008

微软为抵御Linux蚕噬被迫延期XP销售

近日,微软再次宣布,针对低价电脑的Windows XP家庭版的销售截止日期推迟到2010年,比主流PC延长至少两年时间。

此举被业界认为是微软一次无奈妥协,由于去年底华硕的Eee PC打开了超低价电脑市场缺口,吸引众多PC厂商争相跟进,微软停止XP销售将令Linux有机可乘。

不过,令微软为难的是,延长XP的服役时间意味着强调推广Vista的计划受阻。

微软强制升级计划受阻

为了加快Vista的普及力度,此前微软曾计划将OEM厂商预装Windows XP系统的期限定为2008年1月31日,但由于Vista配置要求高、兼容性等问题,微软把XP的期限被延长到了2008年6月30日。虽然遭受OEM 厂商以及用户反对,且反对呼声日益高涨,但微软却一直充耳不闻。按照微软的如意算盘,强制OEM厂商采用Vista,将大大增大Vista的市场占有率, 挽回Vista受市场冷遇的尴尬局面。

正当微软意图凭其在桌面操作系统的垄断地再施故伎之际,PC市场却悄然发生了变化。自去年底华硕推出超低价便携式电脑以来,市场掀起一阵“超低价电脑旋风 ”,超低价电脑冻土市场突然被打开,各大厂商开始纷纷扎堆,包括联想、方正、惠普、 DELL、ACER、富士通、三星、技嘉、微星、海尔都抛出了超低价电脑计划。业内预计,未来四年,超低价便携电脑将井喷增长,2008年的发货量将突破 1000万台,而到2009年将达到2000万。

市场的风云突变令微软束手不及。由于面临微软停止XP销售风险,各大进军超低价便携式电脑市场的PC巨头纷纷转向Linux。而为了让数以千万的桌面系操不至于落入Linux手中,微软随即宣布针对超低价电脑的Windows XP家庭版的销售截止日期将推迟。

微软表示,至少在2010年6月前,英特尔的学生笔记本电脑和华硕的Eee PC都可以安装Windows XP家庭版,同时在新一代Windows系统发布之前,XP还将在市场上销售一年时间,这意味着该系统的销售期限可能延长至2011年或者更晚。

PC厂商不买微软帐

尽管微软主动抛出“橄榄枝”,但曾受尽微软Windows升级策略折磨的PC厂商似乎并不卖帐,在微软宣布面向超低价电脑延长家庭版XP后,早已做好放弃XP心理准备的PC厂商依然力推其预装Linux系统的超低价PC产品。

超低价电脑市场“领头羊”华硕就公开表示,Linux版本拥有华硕专为Eee PC制定的独特界面,消费者在Linux版本的易PC上不仅能够得到使用更方便的界面。倾向于Linux系操的还有惠普、微星等厂商,据了解,这些厂商率 系推出的低价电脑都是Linux操作系统。

除了微软摇摆不定的升级策略外,厂商在超低价电脑市场偏爱Linux,微软的 Windows系统软件许可费高昂也是另一重要因素。据透露,PC厂商购买一个家庭版的Windows XP系统需要为微软支付至少200元人民币,这对市场售价不到3000元的超低价电脑来说,显然难以承受。

据悉,即将在5月中上市的第二代Eee PC中,华硕分别推出采用Windows XP和Linux系统的产品,售价均为3499元,配置Linux操作系统的第二代Eee PC有20GB基于闪存的存储空间,但选择Windows XP配置的用户只有12GB固态硬盘存储空间。而此前,华硕最早推出的易PC的价格仅为2999元。

“很明显,选择采用Windows XP使超低价电脑拉高了成本,这将得超低价电脑失去与普通笔记本电脑的价格优势。”一位国产PC厂商产品经理说。

Vista推广再受打击

此次微软决定保留Windows XP,目的是为防止Linux系统侵袭到该平台,然而,这一举措又为微软带来了另一个问题:XP系统的再次延期退市,或会影响Vista的进一步市场拓展。

据了解,尽管在过去一年,微软不遗余力推广Vista,但到目前为止,大部分用户对于Vista的热情并不高,而调查显示,在广州,Vista的市场占有 率在不到20%。记者在一些国内PC厂商售后维修点了解到,用户电脑的软件问题都出自已安装Vista系统的电脑上,相当数量购买预装Vista电脑的用 户,都要求重装回XP。

为了尽快普及Vista系统,微软今年初称将增加营销费用,而从目前微软的强调升级计划受阻情况来看,微软的营销预算可能要增长不少。据悉,自2006年11月发布以来,微软已投入了约5亿美元的营销费用。

“微软的处境有点两难,一方面该公司希望尽快让用户远离XP普及Vista,而另一方面又不愿看到Linux侵占其市场。”一位分析师表示。

-言论

“Vista是半成品”

微软CEO承认上市一年半Vista仍问题多

在OEM厂商与用户的压力下,微软CEO史蒂夫·鲍尔默终于首次承认Windows Vista仍需改进。“Windows Vista仍是一项正在进展中的工作。”上周四,史蒂夫·鲍尔默的言论震惊业界。此前,很多用户在微软的广告宣传吹嘘下购买了Windows Vista。

“这是一个非常重要的产品。我认为,我们做了很多正确的事情,也有很多需要学习的东西。” 鲍尔默表示。目前,Vista存在很大争议性,比如性能提升、兼容性以等,还有用户抱怨Vista比XP占用的空间大得多。鲍尔默承认,Vista占用空 间确实比XP要大,“而我只能保证它不会变得更大”。

鲍尔默这番话无疑等于向已使用Windows Vista的用户泼了一盆冷头,特别是企业用户。对于这些企业用户来说,每一次系操和更新都是一项巨大工程,“如果连微软都说Vista还有很多需要改进 的地方,那基本可以把Vista看成是一枚炸弹,可以想象那是多么可怕”。一位企业信息管理人员说,”对于如此一个存在许多问题的操作系统,我不明白微软 为何要推销给用户。”

鲍尔默说出这番话的时候正值Windows Vista操作系统处于一个关键时刻。目前,微软正力劝企业和个人用户升级使用Vista。微软于2007年1月份推出Vista,并于上个月发布了首个 主要的Vista升级服务包,其中包括大量的漏洞修复和升级程序,用于修复过去一年Windows Vista在接受市场检验中暴露的问题。

Jupiter Research的分析师迈克尔·加腾伯格表示,鲍尔默用的“正在进展中”这一说法会使用户认为这项工作尚未完成,很难想象在微软力劝企业和个人用户升级使用Vista的关键时刻鲍尔默会说出这样的话。

-业界分析

在台式电脑领域

Linux将超过Vista

费雷斯特市场研究公司(Forrester Research)报告预测,在桌面市场领域Linux将对Windows构成更大的威胁,今年随着Linux在企业市场的普及应用,其市场份额将会迅速增长。

费雷斯特市场研究公司分析师本杰明·格雷(Benjamin Gray)称:“桌面管理人员将会使Windows操作系统平台继续标准化,Linux不会成为企业桌面的首选,因此何以动摇Vista在企业操作系统的 地位?然而客户对Linux桌面需求的增长则说明,其作用会更加突出。明年,随着分销商强化对企业市场Linux的销售,其市场份额一定会进一步增长。”

格雷预计,今年Vista系统将会在北美和欧洲四分之一的企业电脑里安装。届时,企业用户会从XP平台转移到Vista上。但目前,XP系统仍是企业桌面的主流选择。

据悉,该预测是基于对北美和欧洲企业的1001名硬件决策者的调查采访而得出。这其中有43%的受访者来自规模为1000人到4999人的大型企业,有 35%的来自规模为5000到19999人的大型企业,有22%的来自规模有2万员工的以上的超大型跨国企业。这其中有近一半的受访企业表示,他们已制定 了明确安装Vista系统的具体计划,有7%则表示将于今年底开始安装Vista。有 32%的企业表示明年年底才安装使用Vista,另有17%的计划于2009年或是更晚一些来安装。

但是该报告也指出,多数人认为Vista在企业的推广非常之缓慢,有数字表明,目前只占市场的2%。自VISTA推出以来,北美和全球2000强企业中只 有不到3%安装了该系统,而欧洲企业尚未开始安装。许多企业都在等待新的SP1版本推出。微软表示,SP1版本将于明年第一季度推出。

同时该报告还指出,现在已近有9成的企业用户正在使用Windows XP,与此同时有9%的用户依然在使用Windows 2000。格雷因此表示道:“Vista的成功在很大程度上取决于XP用户是否会升级到Vista。

http://linux.chinaunix.net/news/2008/04/22/994330.shtml

标签: , , ,

星期一, 四月 07, 2008

Windows未公开函数揭密——之三

http://www.applevb.com

这次介绍的是如何利用Windows未公开函数实现系统文件操作监视功能。利用该功能可以对Windows下的任何文件操作,包括建立文件、文件夹;删除文件;改变文件大小等操作都可以纪录在案。
首先来介绍实现上面操作的两个未公开函数:SHChangeNotifyRegister和SHChangeNotifyDeregister,SHChangeNotifyRegister函数的定义如下:
Declare Function SHChangeNotifyRegister Lib "shell32" Alias "#2" _
(ByVal hWnd As Long, _
ByVal uFlags As SHCN_ItemFlags, _
ByVal dwEventID As SHCN_EventIDs, _
ByVal uMsg As Long, _
ByVal cItems As Long, _
lpps As PIDLSTRUCT) As Long
其 中参数hWnd指定接受系统通告的窗口句柄,参数uMsg指定消息值,如果函数调用成功,系统就会将hWnd指定的窗口加入到系统通告链中,并且返回系统 通告句柄。当有建立文件等系统操作发生时,系统会向hWnd指定的窗口发送uMsg消息,关于其它参数,会在下面的程序中说明。函数 SHChangeNotifyDeregister的定义如下:
Declare Function SHChangeNotifyDeregister Lib "shell32" Alias "#4" _
(ByVal hNotify As Long) As Boolean
其中参数hNotify指定系统通告的句柄。
下面是操作的具体的VB范例:
首先建立一个新的工程,在Form1中加入一个TextBox控件。在Form1的代码窗口之中加入以下代码:
Option Explicit

Private Sub Form_Load()
If SubClass(hWnd) Then '改变Form1的消息处理函数
If IsIDE Then
Text1.Text = vbCrLf & _
"一个 Windows的文件目录操作即时监视程序," & vbCrLf & "可以监视在Explore中的重命名、新建、删除文" & _
vbCrLf & "件或目录;改变文件关联;插入、取出CD和添加" & vbCrLf & "删除网络共享都可以被该程序记录下来。"
End If
Call SHNotify_Register(hWnd)
Else
Text1 = "系统不支持操作监视程序 :-)"
End If
Move Screen.Width - Width, Screen.Height - Height
End Sub

Private Function IsIDE() As Boolean
On Error GoTo Out
Debug.Print 1 / 0
Out:
IsIDE = Err
End Function

Private Sub Form_Unload(Cancel As Integer)
Call SHNotify_Unregister
Call UnSubClass(hWnd)
End Sub

Public Sub NotificationReceipt(wParam As Long, lParam As Long)
Dim sOut As String
Dim shns As SHNOTIFYSTRUCT
Dim sDisplayname1 As String
Dim sDisplayname2 As String

MoveMemory shns, ByVal wParam, Len(shns)

If shns.dwItem1 Then
sDisplayname1 = GetDisplayNameFromPIDL(shns.dwItem1)
End If

If shns.dwItem2 Then
sDisplayname2 = GetDisplayNameFromPIDL(shns.dwItem2)
End If
sOut = SHNotify_GetEventStr(sDisplayname1, sDisplayname2, lParam) & vbCrLf
Text1 = Text1 & sOut & vbCrLf
Text1.SelStart = Len(Text1)
End Sub
然后在工程中加入三个模块(Bas)文件,将三个文件分别保存为mDef.Bas、mShell.Bas、mSub.Bas。在mDef.Bas中加入以下代码:
'mDef.Bas包含Shell操作的函数和数据类型的定义
Option Explicit

Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, _
pSource As Any, ByVal dwLength As Long)
Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long)

Public Const MAX_PATH = 260
Public Const NOERROR = 0

'SHGetSpecialFolderLocation获得某一个特殊的目录的位置,如果函数调用成功返回NOERROR
'或者一个OLE错误
Declare Function SHGetSpecialFolderLocation Lib "shell32.dll" _
(ByVal hwndOwner As Long, _
ByVal nFolder As SHSpecialFolderIDs, _
pidl As Long) As Long

Public Enum SHSpecialFolderIDs '列出所有Windows下特殊文件夹的ID
CSIDL_DESKTOP = &H0
CSIDL_INTERNET = &H1
CSIDL_PROGRAMS = &H2
CSIDL_CONTROLS = &H3
CSIDL_PRINTERS = &H4
CSIDL_PERSONAL = &H5
CSIDL_FAVORITES = &H6
CSIDL_STARTUP = &H7
CSIDL_RECENT = &H8
CSIDL_SENDTO = &H9
CSIDL_BITBUCKET = &HA
CSIDL_STARTMENU = &HB
CSIDL_DESKTOPDIRECTORY = &H10
CSIDL_DRIVES = &H11
CSIDL_NETWORK = &H12
CSIDL_NETHOOD = &H13
CSIDL_FONTS = &H14
CSIDL_TEMPLATES = &H15
CSIDL_COMMON_STARTMENU = &H16
CSIDL_COMMON_PROGRAMS = &H17
CSIDL_COMMON_STARTUP = &H18
CSIDL_COMMON_DESKTOPDIRECTORY = &H19
CSIDL_APPDATA = &H1A
CSIDL_PRINTHOOD = &H1B
CSIDL_ALTSTARTUP = &H1D
CSIDL_COMMON_ALTSTARTUP = &H1E
CSIDL_COMMON_FAVORITES = &H1F
CSIDL_INTERNET_CACHE = &H20
CSIDL_COOKIES = &H21
CSIDL_HISTORY = &H22
End Enum

'SHGetPathFromIDList函数将一个Item转换为文件路径
Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _
(ByVal pidl As Long, _
ByVal pszPath As String) As Long

'SHGetFileInfoPidl函数获得某个文件对象的信息。
Declare Function SHGetFileInfoPidl Lib "shell32" Alias "SHGetFileInfoA" _
(ByVal pidl As Long, _
ByVal dwFileAttributes As Long, _
psfib As SHFILEINFOBYTE, _
ByVal cbFileInfo As Long, _
ByVal uFlags As SHGFI_flags) As Long

Public Type SHFILEINFOBYTE
hIcon As Long
iIcon As Long
dwAttributes As Long
szDisplayName(1 To MAX_PATH) As Byte
szTypeName(1 To 80) As Byte
End Type

Declare Function SHGetFileInfo Lib "shell32" Alias "SHGetFileInfoA" _
(ByVal pszPath As String, _
ByVal dwFileAttributes As Long, _
psfi As SHFILEINFO, _
ByVal cbFileInfo As Long, _
ByVal uFlags As SHGFI_flags) As Long

Public Type SHFILEINFO
hIcon As Long
iIcon As Long
dwAttributes As Long
szDisplayName As String * MAX_PATH
szTypeName As String * 80
End Type

Enum SHGFI_flags
SHGFI_LARGEICON = &H0
SHGFI_SMALLICON = &H1
SHGFI_OPENICON = &H2
SHGFI_SHELLICONSIZE = &H4
SHGFI_PIDL = &H8
SHGFI_USEFILEATTRIBUTES = &H10
SHGFI_ICON = &H100
SHGFI_DISPLAYNAME = &H200
SHGFI_TYPENAME = &H400
SHGFI_ATTRIBUTES = &H800
SHGFI_ICONLOCATION = &H1000
SHGFI_EXETYPE = &H2000
SHGFI_SYSICONINDEX = &H4000
SHGFI_LINKOVERLAY = &H8000
SHGFI_SELECTED = &H10000
End Enum

'根据一个特定文件夹对象的ID获得它的目录pidl
Public Function GetPIDLFromFolderID(hOwner As Long, nFolder As SHSpecialFolderIDs) As Long
Dim pidl As Long
If SHGetSpecialFolderLocation(hOwner, nFolder, pidl) = NOERROR Then
GetPIDLFromFolderID = pidl
End If
End Function

Public Function GetDisplayNameFromPIDL(pidl As Long) As String
Dim sfib As SHFILEINFOBYTE
If SHGetFileInfoPidl(pidl, 0, sfib, Len(sfib), SHGFI_PIDL Or SHGFI_DISPLAYNAME) Then
GetDisplayNameFromPIDL = GetStrFromBufferA(StrConv(sfib.szDisplayName, vbUnicode))
End If
End Function

Public Function GetPathFromPIDL(pidl As Long) As String
Dim sPath As String * MAX_PATH
If SHGetPathFromIDList(pidl, sPath) Then
GetPathFromPIDL = GetStrFromBufferA(sPath)
End If
End Function

Public Function GetStrFromBufferA(sz As String) As String
If InStr(sz, vbNullChar) Then
GetStrFromBufferA = Left$(sz, InStr(sz, vbNullChar) - 1)
Else
GetStrFromBufferA = sz
End If
End Function

在mShell.Bas中加入以下代码:
'mShell.Bas函数包含注册和反注册系统通告以及文件夹信息转换的函数
Option Explicit

Private m_hSHNotify As Long '系统消息通告句柄
Private m_pidlDesktop As Long

'定义系统通告的消息值
Public Const WM_SHNOTIFY = &H401

Public Type PIDLSTRUCT
pidl As Long
bWatchSubFolders As Long
End Type

Declare Function SHChangeNotifyRegister Lib "shell32" Alias "#2" _
(ByVal hWnd As Long, _
ByVal uFlags As SHCN_ItemFlags, _
ByVal dwEventID As SHCN_EventIDs, _
ByVal uMsg As Long, _
ByVal cItems As Long, _
lpps As PIDLSTRUCT) As Long

Type SHNOTIFYSTRUCT
dwItem1 As Long
dwItem2 As Long
End Type

Declare Function SHChangeNotifyDeregister Lib "shell32" Alias "#4" _
(ByVal hNotify As Long) As Boolean

Declare Sub SHChangeNotify Lib "shell32" _
(ByVal wEventId As SHCN_EventIDs, _
ByVal uFlags As SHCN_ItemFlags, _
ByVal dwItem1 As Long, _
ByVal dwItem2 As Long)

Public Enum SHCN_EventIDs
SHCNE_RENAMEITEM = &H1
SHCNE_CREATE = &H2
SHCNE_DELETE = &H4
SHCNE_MKDIR = &H8
SHCNE_RMDIR = &H10
SHCNE_MEDIAINSERTED = &H20
SHCNE_MEDIAREMOVED = &H40
SHCNE_DRIVEREMOVED = &H80
SHCNE_DRIVEADD = &H100
SHCNE_NETSHARE = &H200
SHCNE_NETUNSHARE = &H400
SHCNE_ATTRIBUTES = &H800
SHCNE_UPDATEDIR = &H1000
SHCNE_UPDATEITEM = &H2000
SHCNE_SERVERDISCONNECT = &H4000
SHCNE_UPDATEIMAGE = &H8000&
SHCNE_DRIVEADDGUI = &H10000
SHCNE_RENAMEFOLDER = &H20000
SHCNE_FREESPACE = &H40000
SHCNE_ASSOCCHANGED = &H8000000

SHCNE_DISKEVENTS = &H2381F
SHCNE_GLOBALEVENTS = &HC0581E0
SHCNE_ALLEVENTS = &H7FFFFFFF
SHCNE_INTERRUPT = &H80000000
End Enum

#If (WIN32_IE >= &H400) Then
Public Const SHCNEE_ORDERCHANGED = &H2
#End If

Public Enum SHCN_ItemFlags
SHCNF_IDLIST = &H0
SHCNF_PATHA = &H1
SHCNF_PRINTERA = &H2
SHCNF_DWORD = &H3
SHCNF_PATHW = &H5
SHCNF_PRINTERW = &H6
SHCNF_TYPE = &HFF
SHCNF_FLUSH = &H1000
SHCNF_FLUSHNOWAIT = &H2000

#If UNICODE Then
SHCNF_PATH = SHCNF_PATHW
SHCNF_PRINTER = SHCNF_PRINTERW
#Else
SHCNF_PATH = SHCNF_PATHA
SHCNF_PRINTER = SHCNF_PRINTERA
#End If
End Enum

Public Function SHNotify_Register(hWnd As Long) As Boolean
Dim ps As PIDLSTRUCT

If (m_hSHNotify = 0) Then

m_pidlDesktop = GetPIDLFromFolderID(0, CSIDL_DESKTOP)
If m_pidlDesktop Then

ps.pidl = m_pidlDesktop
ps.bWatchSubFolders = True

'注册Windows监视,将获得的句柄保存到m_hSHNotify中
m_hSHNotify = SHChangeNotifyRegister(hWnd, SHCNF_TYPE Or SHCNF_IDLIST, _
SHCNE_ALLEVENTS Or SHCNE_INTERRUPT, _
WM_SHNOTIFY, 1, ps)
SHNotify_Register = CBool(m_hSHNotify)

Else
Call CoTaskMemFree(m_pidlDesktop)
End If
End If
End Function

Public Function SHNotify_Unregister() As Boolean
If m_hSHNotify Then
If SHChangeNotifyDeregister(m_hSHNotify) Then
m_hSHNotify = 0
Call CoTaskMemFree(m_pidlDesktop)
m_pidlDesktop = 0
SHNotify_Unregister = True
End If
End If
End Function

Public Function SHNotify_GetEventStr(strPath1, strPath2 As String, dwEventID As Long) As String
Dim sEvent As String

Select Case dwEventID
Case SHCNE_RENAMEITEM: sEvent = "重命名文件" + strPath1 + "为" + strPath2
Case SHCNE_CREATE: sEvent = "建立文件 文件名:" + strPath1
Case SHCNE_DELETE: sEvent = "删除文件 文件名:" + strPath1
Case SHCNE_MKDIR: sEvent = "新建目录 目录名:" + strPath1
Case SHCNE_RMDIR: sEvent = "删除目录 目录名:" + strPath1
Case SHCNE_MEDIAINSERTED: sEvent = strPath1 + "中插入可移动存储介质"
Case SHCNE_MEDIAREMOVED: sEvent = strPath1 + "中移去可移动存储介质"
Case SHCNE_DRIVEREMOVED: sEvent = "移去驱动器" + strPath1
Case SHCNE_DRIVEADD: sEvent = "添加驱动器" + strPath1
Case SHCNE_NETSHARE: sEvent = "改变目录" + strPath1 + "的共享属性"
Case SHCNE_UPDATEDIR: sEvent = "更新目录" + strPath1
Case SHCNE_UPDATEITEM: sEvent = "更新文件 文件名:" + strPath1
Case SHCNE_SERVERDISCONNECT: sEvent = "断开与服务器的连" + strPath1 + " " + strPath2
Case SHCNE_UPDATEIMAGE: sEvent = "SHCNE_UPDATEIMAGE"
Case SHCNE_DRIVEADDGUI: sEvent = "SHCNE_DRIVEADDGUI"
Case SHCNE_RENAMEFOLDER: sEvent = "重命名文件夹" + strPath1 + "为" + strPath2
Case SHCNE_FREESPACE: sEvent = "磁盘空间大小改变"

Case SHCNE_ASSOCCHANGED: sEvent = "改变文件关联"
End Select

SHNotify_GetEventStr = sEvent
End Function

在mSub.Bas中加入以下代码:
'mSub函数包括窗口的消息处理函数
Option Explicit

Private Const WM_NCDESTROY = &H82
Private Const GWL_WNDPROC = (-4)
Private Const OLDWNDPROC = "OldWndProc"

Private Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal _
hWnd As Long, ByVal lpString As String) As Long
Private Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal _
hWnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
Private Declare Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal _
hWnd As Long, ByVal lpString As String) As Long

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long

Public Function SubClass(hWnd As Long) As Boolean
Dim lpfnOld As Long
Dim fSuccess As Boolean

If (GetProp(hWnd, OLDWNDPROC) = 0) Then
lpfnOld = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WndProc)
If lpfnOld Then
fSuccess = SetProp(hWnd, OLDWNDPROC, lpfnOld)
End If
End If

If fSuccess Then
SubClass = True
Else
If lpfnOld Then Call UnSubClass(hWnd)
MsgBox "Unable to successfully subclass &H" & Hex(hWnd), vbCritical
End If
End Function

Public Function UnSubClass(hWnd As Long) As Boolean
Dim lpfnOld As Long

lpfnOld = GetProp(hWnd, OLDWNDPROC)
If lpfnOld Then
If RemoveProp(hWnd, OLDWNDPROC) Then
UnSubClass = SetWindowLong(hWnd, GWL_WNDPROC, lpfnOld)
End If
End If
End Function

Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As _
Long, ByVal lParam As Long) As Long
Select Case uMsg
Case WM_SHNOTIFY '处理系统消息通告函数
Call Form1.NotificationReceipt(wParam, lParam)
Case WM_NCDESTROY
Call UnSubClass(hWnd)
MsgBox "Unubclassed &H" & Hex(hWnd), vbCritical, "WndProc Error"
End Select

WndProc = CallWindowProc(GetProp(hWnd, OLDWNDPROC), hWnd, uMsg, wParam, lParam)
End Function

保存文件,然后运行程序,然后你可以在Explore中试着建立或者删除一个文件或者文件夹,在Form中可以看到你所做的操作已经被纪录并且显示到TextBox中了。
现 在分析以下上面的程序,上面的程序首先调用SHChangeNotifyRegister函数将Form添加到系统消息通告链中,并利用 SetWindowLong函数改变Form的缺省的消息处理函数,当接受到系统通告消息后,根据传递的参数获得系统通告的内容并且显示在文本窗口中。退 出程序时调用SHChangeNotifyDeregister函数注销系统消息通告。

http://dev.csdn.net/develop/article/3/3297.shtm

标签: ,

星期四, 三月 20, 2008

wxWidgets 2.8.7编译

使用Code::Blocks带的mingw32编译,参数如下:
mingw32-make -f makefile.gcc BUILD=release UNICODE=1 USE_ODBC=1
共耗时18'。机器配置Intel Pentium 4 3.0G 1G Mem.以后打算换个AMD的4核试试。平台就不用Windows了。
其中,因为原来安装了UnxUtils几次提示zsh错误。有此方面问题的兄弟引以为戒。需要在path里禁用之。

标签: , , ,

X Window下的字体缩放和TTF的应用

X Window下的字体缩放和TTF的应用(转)


字体属于最直观的东西,直接影响最终的显示和打印结果。在图形界面和所见既所得的要求下,如何发挥X Window在字体方面的能力,是大家十分关心的问题。现在XFree86 4.0已经出来,在TTF方面的扩展已经尘埃落定,所以有了本文。

X Window在字体方面的能力十分强大。X Window的结构很清晰,统一使用X逻辑字体描述XLFD(X Logical Font Description)描述各式各样的字体。每增加一种字体,只是增加一个模块,XLFD并没有多大变化。这样保证了兼容性,避免系统出现大的动荡。但 负作用也是有的,随着功能的增加,我们会发现耗内存越来越多,速度自然也越来越慢了:-)

X Window使用X字体服务器XFS处理字体。XFree86附带有一个网络字体服务器xfs,还有每一个X Server都是XFS。就性能而言,自然是内部的XFS快很多。目前XFree86 4.0支持bdf/pcf,Type1,TrueTypeFont等几种字体格式。

其中bdf/pcf是最基本的格式,TTF可以完美实现无级缩放。
X 逻辑字体描述(X Logical Font Description)的简单说明:
// font fields
// -fndry-fmly-wght-slant-sWdth-adstyl-pxlsz-ptSz-resx-resy-spc-avg Wdth-rgstry-encdng
// fndry -> foundy
// fmly -> family, font style
// wght -> weight
// slant
// sWdth -> ? width
// adstyl -> addtion style
// pxlsz -> pixel size
// ptSz -> point size
// resx -> resolution x
// resy -> resolution y
// spc -> space
// avgWdth -> average width
// rgstry -> register
// encdng -> encoding
example:
-cclib-song-medium-r-normal-jiantizi-16-160-75-75-c-160-gb2312.1980-0

其中:
cclib : 制造商
song : 字体族, 宋体
medium: 线权重(中等), 还有bold(粗体)选项
r : 倾斜, r(Roman), i(Italic), o(Oblique)
normal: 字符集宽度, 此外还有 condensed, narrow, double
jiantizi: 附加说明(简体字)
16: 以像素衡量的宽度.
160: 点数*10
75(1): 水平分辨率(dpi)
75(2): 垂直分辨率(dpi)
c: 间距, (?), m: fixed width, p: variable width
160: 平均宽度(10*pixels)
gb2312.1980: 注册字符集,标准名
0: 第0套,基本集
字体描述文件
在字体同一目录下,有两个文件指导X window如何安装使用字体:
fonts.dir/fonts.alias。虽然fonts.dir可由实用程序mkfontdir生成,但生成的文件中字体的次序不一定合适,所以有时需要人工调整。
fonts.dir 格式:
第一行:字体文件的数目
后面:字体文件 X 逻辑字体描述(字体真名)
......
fonts.dir example:
2
ccs16.pcf.gz -cclib-song-medium-r-normal-jiantizi-16-160-75-75-c-160-gb2312.1980-0
ccs24.pcf.gz -cclib-song-medium-r-normal-jiantizi-24-240-75-75-c-240-gb2312.1980-0
fonts.alias 格式:
字体别名 X 逻辑字体描述(字体真名)
......
fonts.alias example:
ccs16 -cclib-song-medium-r-normal-jiantizi-16-160-75-75-c-160-gb2312.1980-0
ccs24 -cclib-song-medium-r-normal-jiantizi-24-240-75-75-c-240-gb2312.1980-0
这样在使用过程中,程序既可以使用字体真名,也可以使用字体别名装载X字体。

X字体的使用
应用程序调用XLoad(Query)Font函数装载字体。X window会尽量解释和装载字体,其中包括参数里使用"*","?"通配符,还有缩放字体。其中X 逻辑字体描述字段对字体缩放有直接影响的是pixel size/point size, average width字段。其中pixel size的优先级大于point size。也就是,如果传给XLoadFont的字体不存在,X window会根据现有的一个名字匹配,大小(pixel size/point size, average width)不同的字体,在内存里生成一个新字体。

因为X window下的中文字体很少,一般只提供16和24点阵两种大小。所以字体缩放机制就显得很重要。这种机制的好处是只须提供少量的字体,就可以应付大多 数情况。缺点也是有的,就是生成字体的速度很慢,延迟是以秒记的。如果是GB2312字体还好,不到7000个字。而Unicode或GBK字体,汉字就 有20902多个,一个个进行缩放,延迟可想而知。但要注意的是,X window只是在装载生成字体时有延迟,字体生成后,XDraw*函数显示速度并没有延迟。
下面举例说明。如果有字体:
ccs16.pcf.gz -cclib-song-medium-r-normal-jiantizi-16-160-75-75-c-160-gb2312.1980-0
想用字体:
"-*-song-medium-r-normal-jiantizi-12-120-75-75-c-100-gb2312.1980-0"
程序里只须直接调用即可:
......
char *font_name = "-*-song-medium-r-normal-jiantizi-12-120-75-75-c-100-gb2312.1980-0";
XFontStruct *zh_font;
......
zh_font = XLoadFont(display, font_name);
if (zh_font == NULL) {
printf("not find this font: %s\n", font_name);
exit(1);
}
......

这里要讨论字体缩放机制,是为了解决X外挂式中文平台的字符串定位问题。如果光标要定在两个字符之间,就要知道这点的位置。X应用程序一般是调用函数 XTextWidth(16),XTextExtents(16),XQueryTextExtents(16)以确定字符串的宽度。所以X外挂式中文平 台要截取这些函数以便对中英文混排的字符串进行准确定位。但有些程序为了速度,是调用XGetFontProperty函数或直接在 XFontStruct结构里取得单个字符的宽度,乘上字符个数得到字符串的宽度。如果ASCII字体有标准高宽比,也是没有问题。所谓标准高宽比就是 ASCII字体的宽:高为1/2,相应的中文字体就是1:1。如果不是这样,光标定位就有问题。再有就是字符高度,一般是中文字体略高于ASCII字体就 美观了。但具体数值要控制好,否则太矮不好看,太高又会被削去头部。所以字间距和行间距目前是很烦恼的问题。解决的方法可能有一些:
1,截获更多的函数,或修改ASCII字体的高度和宽度。这要求对X window有很深的了解。这也是一个吃力不讨好的方案,因为总有疏漏,X window的函数也会发展和变化,那么就会有遗憾。cleex for Linux 1.0在速度和定位上较好地解决了这个问题,可能是使用了这个方案。
2,使用字体缩放机制,使汉字大小和ASCII字体相匹配。这个方案的问题是装载字体的速度和耗费的资源。我实验了这个方案,使用NetScape浏览网 页,发现很多时间花在了装载字体上。而且,如何管理这些字体也是一个问题。使用TTF字体可能可以完美地解决这个问题。我使用TLC4.0的 ZhWinPro2.0,发现以前定位不准的软件都没有问题了。看来使用TTF字体是今后的方向。应该看到,一个好的XFS,就算不支持TTF,也可以实 现字体的无级缩放。只是bdf/pcf这类字体格式存储的字形信息少,在显示效果上就不及TTF完美,但装载速度感觉就比TTF快。并且在14点阵以 下,TTF的效果倒反不及bdf/pcf。因此今后bdf/pcf主要使用在小点阵低速的环境中,而TTF将用在强调细节和美观的环境里,如字处理。事实 上,X11R6以后的XLFD的功能十分强大,增加矩阵型XLFD和增强别名机制。只需通过XLFD的变换,就可以实现字体的缩放,倾斜,镜像,斜写和环 写的功能,如同MS WORD里的艺术字那样的效果。因为英文水平不高,不敢乱说,有兴趣的可以查看http://www.winehq.com/x11r6_fonts_94.pdf或者XFree86源代码的随机文档。

TTF以曲线描述字体,可以在各种大小的环境下还原字形。在FreeType的随机文档里有一些这方面的介绍。可以说,XFree86有了TTF,就有了 在所见既所得方面和MS WINDOWS较量的实力。目前XFree86使用的TTF驱动模块是FreeType,这是底层的TTF解释模块,用来把TTF的字形描述转换为可用的 光栅字形。FreeType目前稳定的版本是1.3.1。因为在一些算法上和大公司有专利纠纷,他们决定FreeType依然是freedom。于是放弃 成熟的1.x版,加速开发更好的2.x。这官司让人关注,而FreeType的做法也让人敬佩。有了驱动模块,要想在XFree86下显示这些字,还需要 高一层的X字体服务器(XFS)。目前在XFree86下TTF的XFS有X-TT和xfsft两个,都是使用FreeType作为底层,在实现上个有特 色。XFree86 4.0目前接纳了这两个软件,同时也接纳了这两个软件对fonts.dir文件格式的扩展。

X-TT是日本人的作品。可能同样是要使用汉字,X-TT显示的汉字感觉上要比xfsft的要美观些。X-TT还有一个特色就是把XFree86的字体处 理模块分离出来,做成一个动态链接库libfont.so。但是不知什么原因,XFree86 4.0没有接受这个方案,继续使用静态链接库font.a。

X-TT目前可以通过XLFD的变换把ISO10646编码的TTF转化为GB2312,BIG5,JIS,KSC等编码标准的字体。但是X-TT软件本 身没有提供GBK编码的支持。国内两个提供使用TTF字体的Linux厂商(TurboLinux和红旗Linux)都选用X-TT作为XFS,同时提供 了GBK的支持。例如RF1.1把所有的转换表,包括GBK的,都做成动态链接库形式的convert modules,放在/usr/X11R6/lib/modules/codeconv下。如果这两个厂商的方案能进入X-TT的原始发行版中,进而进入 XFree86今后的发行版中,将是中国Linux界的一件大事。xfsft有一个特点就是比较小巧,功能不多,够用就行。XFree86 4.0缺省就是使用xfsft模块。xfsft在变换TTF的编码时,使用的是外部的转换表。这也是我从3.3.3.1到现在的4.0一直使用xfsft 的原因。xfsft本身也只提供了GB2312和BIG5的转换表,没有提供GBK的支持。但我从Unicode的网站下载了 GBK->Unicode的转换表,简单修改配置文件,就可以使用GBK编码标准的字体了。

前面所说的显示字形美观问题,一个是指个人的感觉,另一个是指在小点阵下中文TTF的显示问题。所谓小点阵字体,是指14点阵以下的字体。目前不论是X- TT还是xfsft,在这种情况下,都不及同样大小的pcf字体美观(我对比使用的是cleex的12和14点阵字体,还有RF1.1提供的一个12点阵 的GB2312编码的点阵字体)。这是中文TTF的问题。观察我们的汉字笔画,点、横、竖、撇、捺、折、钩,从头到尾粗细都是变化的。在小点阵的情况 下,TTF既想表达这些变化,又要丢失一些细节,就会造成中文字横不平,竖不直,都有些打折,同时点和钩常常丢失,因此显示出来的中文字怎么看都不顺眼。 反观英文字母,基本上是粗细相等的线条,上面对比用的小点阵中文pcf字体,笔画基本上也是一条棍子捅到底。其实,在这种情况下,我们要求的不是细节,而 是中文字横平竖直的基本要求,所以TTF的曲线描述这时倒反成了累赘。为解决这个问题,现在的中文TTF都会内嵌小点阵字体。因为没有看过 FreeType,X-TT和xfsft的源代码,不能确定它们的实际效果。但目前MS WINDOWS95/98中文版在显示小点阵中文字体方面比X-TT和xfsft的要好。当然,这也是一个感觉。

ISO10646的TTF通过XLFD变换而变化为其它编码标准的字体,可以算是Unicode在XFree86中的一个应用。通过这个功 能,XFree86只需一套ISO10646编码标准的TTF,就可以同时提供中文,日文,韩文的显示。关键就在于那些转换表的应用。原理很简 单,XLFD最后两个域是注册名和编码号,XFS在处理XLFD时,识别这两个区域,通过配置文件和转换表,就可以提供其它编码标准的字体。

因为在XFree86 3.x下配置TTF的XFS有点麻烦,而且XFree86 3.x很快就成为历史,所以下面主要讨论在XFree86 4.0下如何配置xfsft以支持GBK。如果要使用X-TT,可以安装TLC4.X或RF1.1,不过两者都不好移植到其它Linux套件中。还有一个 是北京腾图出的Manderake Linux 7.0也是使用X-TT。

取来ISO10646的TTF,放在一个目录中:
#ls /usr/X11R6/lib/X11/fonts/FreeType -l
-rw-r--r-- 1 root root 2496 May 3 10:04 encodings.dir
-rw-r--r-- 1 root root 689 May 3 10:10 fonts.alias
-rw-r--r-- 1 root root 1968 May 3 08:50 fonts.dir
-rw-r--r-- 1 root root 1968 May 3 10:04 fonts.scale
-rw-r--r-- 1 root root 3595788 Apr 8 08:54 fzfsjw.ttf
-rw-r--r-- 1 root root 10210620 Apr 8 08:55 fzhtk.ttf
-rw-r--r-- 1 root root 3759712 Apr 8 08:55 fzktjw.ttf
-rw-r--r-- 1 root root 3978284 Apr 8 08:55 fzlsjw.ttf
-rw-r--r-- 1 root root 2763072 Apr 8 08:55 fzssjw.ttf
-rw-r--r-- 1 root root 9300964 Apr 8 08:55 fzssk.ttf
-rw-r--r-- 1 root root 4762912 Apr 8 08:55 fzwbjw.ttf
其中fzssk.ttf和fzhtk.ttf是ISO10646的TTF。
制作fonts.dir和fonts.alias
#cat /usr/X11R6/lib/X11/fonts/FreeType/fonts.dir
13
fzssjw.ttf -freetype-song-medium-r-normal-jiantizi-0-0-0-0-c-0-gb2312.1980-0
fzktjw.ttf -freetype-kai-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
fzlsjw.ttf -freetype-lishu-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
fzwbjw.ttf -freetype-weibei-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
fzfsjw.ttf -freetype-fang-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
fzssk.ttf -freetype-song-medium-r-normal--0-0-0-0-c-0-iso10646.1993-1
fzssk.ttf -freetype-song-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
fzssk.ttf -freetype-song-medium-r-normal--0-0-0-0-c-0-gb13000.1993-1
fzssk.ttf -freetype-song-medium-r-normal--0-0-0-0-c-0-big5.eten-0
fzhtk.ttf -freetype-hei-medium-r-normal--0-0-0-0-c-0-iso10646.1993-1
fzhtk.ttf -freetype-hei-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
fzhtk.ttf -freetype-hei-medium-r-normal--0-0-0-0-c-0-gb13000.1993-1
fzhtk.ttf -freetype-hei-medium-r-normal--0-0-0-0-c-0-big5.eten-0
#cat /usr/X11R6/lib/X11/fonts/FreeType/fonts.alias
-freetype-song-medium-r-normal--0-0-0-0-c-0-gb2312.1980-1
-freetype-song-medium-r-normal--0-0-0-0-c-0-gb13000.1993-1
-freetype-hei-medium-r-normal--0-0-0-0-c-0--gb2312.1980-1
-freetype-hei-medium-r-normal--0-0-0-0-c-0-gb13000.1993-1
把/usr/X11R6/lib/X11/fonts/FreeType加入XFree86的字体目录中,在/etc/X11/XF86Config中的Section "Files"加入
FontPath "/usr/X11R6/lib/X11/fonts/FreeType/"

上面-*-gb13000.1993-1就是GBK字体。这名字在概念上是有些错误,但目前也没有更好的名字,而且大家都这么用,也就习惯了。如果是使用 TLC4.X或RF1.1,设置到此可以结束了。如果是北京腾图出的Manderake Linux 7.0,把RF1.1的/usr/X11R6/lib/modules/codeconv/GB13000.so拷贝到相同的目录下也可以了。

在XFree86 4.0下X-TT和xfsft是两个独立的模块,使用其中一个,就不能用另一个。如果在/etc/X11/XF86Config的Section "Module"是Load "freetype"则使用xfsft,如果是Load "xtt"则使用X-TT。

如果安装有xfsft,就会有一个目录/usr/X11R6/lib/X11/fonts/encodings。
其中CJK的编码转换表放在/usr/X11R6/lib/X11/fonts/encodings/large:
#ls /usr/X11R6/lib/X11/fonts/encodings/large -l
-rw-r--r-- 1 root wheel 65878 Mar 10 06:12 big5.eten-0.enc.gz
-rw-r--r-- 1 root wheel 693 May 3 10:00 encodings.dir
-rw-r--r-- 1 root root 105183 May 3 10:01 gb13000.1993-1.enc.gz
-rw-r--r-- 1 root wheel 33215 Mar 10 06:12 gb2312.1980-0.enc.gz
-rw-r--r-- 1 root wheel 184 Mar 10 06:12 jisx0201.1976-0.enc.gz
-rw-r--r-- 1 root wheel 32847 Mar 10 06:12 jisx0208.1983-0.enc.gz
-rw-r--r-- 1 root wheel 34392 Mar 10 06:12 jisx0208.1990-0.enc.gz
-rw-r--r-- 1 root wheel 23811 Mar 10 06:12 jisx0212.1990-0.enc.gz
-rw-r--r-- 1 root wheel 25951 Mar 10 06:12 ksc5601.1987-0.enc.gz
#cat /usr/X11R6/lib/X11/fonts/encodings/large/encodings.dir
9
big5.eten-0 /usr/X11R6/lib/X11/fonts/encodings/large/big5.eten-0.enc.gz
jisx0212.1990-0 /usr/X11R6/lib/X11/fonts/encodings/large/jisx0212.1990-0.enc.gz
jisx0208.1990-0 /usr/X11R6/lib/X11/fonts/encodings/large/jisx0208.1990-0.enc.gz
jisx0208.1983-0 /usr/X11R6/lib/X11/fonts/encodings/large/jisx0208.1983-0.enc.gz
big5-0 /usr/X11R6/lib/X11/fonts/encodings/large/big5.eten-0.enc.gz
gb2312.1980-0 /usr/X11R6/lib/X11/fonts/encodings/large/gb2312.1980-0.enc.gz
gb13000.1993-1 /usr/X11R6/lib/X11/fonts/encodings/large/gb13000.1993-1.enc.gz
jisx0201.1976-0 /usr/X11R6/lib/X11/fonts/encodings/large/jisx0201.1976-0.enc.gz
ksc5601.1987-0 /usr/X11R6/lib/X11/fonts/encodings/large/ksc5601.1987-0.enc.gz
其中gb13000.1993-1.enc.gz是GBK->Unicode编码转换表,是从Unicode下载转换表后按照enc文件格式自己制 作的。关于enc文件格式,可以看xfsft的随机文档,很简单的。因为gb13000.1993-1.enc.gz大于100kb,所以不能附上。
接着制作TTF目录下的fonts.scale和encodings.dir
#cp /usr/X11R6/lib/X11/fonts/FreeType/fonts.dir /usr/X11R6/lib/X11/
fonts/FreeType/fonts.scale
#cat /usr/X11R6/lib/X11/fonts/FreeType/encodings.dir
9
big5.eten-0 /usr/X11R6/lib/X11/fonts/encodings/large/big5.eten-0.enc.gz
jisx0212.1990-0 /usr/X11R6/lib/X11/fonts/encodings/large/jisx0212.1990-0.enc.gz
jisx0208.1990-0 /usr/X11R6/lib/X11/fonts/encodings/large/jisx0208.1990-0.enc.gz
jisx0208.1983-0 /usr/X11R6/lib/X11/fonts/encodings/large/jisx0208.1983-0.enc.gz
big5-0 /usr/X11R6/lib/X11/fonts/encodings/large/big5.eten-0.enc.gz
gb2312.1980-0 /usr/X11R6/lib/X11/fonts/encodings/large/gb2312.1980-0.enc.gz
gb13000.1993-1 /usr/X11R6/lib/X11/fonts/encodings/large/gb13000.1993-1.enc.gz
jisx0201.1976-0 /usr/X11R6/lib/X11/fonts/encodings/large/jisx0201.1976-0.enc.gz
ksc5601.1987-0 /usr/X11R6/lib/X11/fonts/encodings/large/ksc5601.1987-0.enc.gz
重新启动XF86,打开一个xterm
#xlsfonts | grep freetype
-freetype-fang-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
-freetype-hei-medium-r-normal--0-0-0-0-c-0--gb2312.1980-1
-freetype-hei-medium-r-normal--0-0-0-0-c-0-big5.eten-0
-freetype-hei-medium-r-normal--0-0-0-0-c-0-gb13000.1993-1
-freetype-hei-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
-freetype-hei-medium-r-normal--0-0-0-0-c-0-iso10646.1993-1
-freetype-kai-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
-freetype-lishu-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
-freetype-song-medium-r-normal--0-0-0-0-c-0-big5.eten-0
-freetype-song-medium-r-normal--0-0-0-0-c-0-gb13000.1993-1
-freetype-song-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
-freetype-song-medium-r-normal--0-0-0-0-c-0-gb2312.1980-1
-freetype-song-medium-r-normal--0-0-0-0-c-0-iso10646.1993-1
-freetype-song-medium-r-normal-jiantizi-0-0-0-0-c-0-gb2312.1980-0
-freetype-weibei-medium-r-normal--0-0-0-0-c-0-gb2312.1980-0
#xfd -fn -freetype-song-medium-r-normal--0-0-0-0-c-0-gb13000.1993-1 &

http://www.bross.cn/modules/discuz/viewthread.php?tid=359

标签: , ,

字体缩放

自己定义字体,选进设备描述表,用,释放
如果在OnSize()中:
CClientDC dc;
CFont font;
LOGFONT log;
GetObject(::GetStockObject(DEFAULT_GUI_FONT),sizeof(log),&log);
log.lfHeight=20; //改
log.lfWidth=20; //改
log.lfCharSet=GB2312_CHARSET;
lstrcpy(log.lfFaceName,"宋体"); //改
font.CreateFontIndirect(&log);
CFont* oldfont=pDC->SelectObject(&font);
dc->TextOut("LLM");
dc->SelectObject(oldfont);

http://topic.csdn.net/t/20021101/13/1139652.html

感觉可行

标签: ,

星期二, 三月 18, 2008

Windows上配置Code::Blocks + wxWidgets

27号晚上我问一个做共享软件的朋友Lazaru(基于FreePascal的跨平台IDE,类似于Delphi)做桌面软件如何,他推荐用Code::Blocks,说Nightly Build已经很稳定,正式版很快就发布了,接着果然28号就发布了正式版。

本文内容来自Code::Blocks wiki上的WxWindowsQuickRef,本文内容并非按照原文完全逐字逐句的翻译。

Code::Blocks是一个跨平台的C++IDE,支持Windows、Linux、MacOSX。同时他还支持各种不同的编译器,如GNU/MinGW C/C++,VC++ 6.0/2003/2005/2008,Borland C++,Digital Mars等等各种不同的编译器。

经过14个组员长达2年对Code::Blocks的全部重写,终于发布了正式版8.02,这个版本更包括了对构建基于wxWidgets的跨平台GUI程序的支持,堪比Visual C++。

wxWidgets则是一个十分优秀的跨平台的GUI框架,用其编写的C++应用程序可以十分方便地迁移到不同的系统上去。

Code::Blocks + wxWidgets两个同是支持跨平台的IDE和框架,使得跨平台的编程非常方便。然而Code::Blocks虽然包含了对wxWidgets的支持, 但是却没有包含wxWidgets的构建环境,我们必须手动进行配置。另外,Code::Blocks有一个安装包包含了MinGW的编译器,如果使用别 的编译器,同样也需要自己进行相应的配置。

前提准备

编译器

你至少应该正确安装了免费的MinGW/GCC编译器或者是某种微软的编译器Express editions是免费的,但是你还需要安装Platform SDK)。如果是用MinGW/GCC,至少要准备gcc-core、gcc-g++、binutils、w32api以及mingw32-make包;同时,确保包含编译器可执行文件的目录(一般是C:\MinGW\bin)在Windows的PATH环境变量中。

如果选择MinGW/GCC编译器,可以在直接选择包含MinGW的Code::Blocks安装包,见下一节。

最新版的Code::Blocks

请下载最新的8.02发布版。尚未选择编译器可以选择包含MinGW的安装包

wxWidgets

你可以选择下载wxWidgets的源代码然后自己进行构建,或者是直接安装预编译的wxPack。

wxWidgets源代码

安装包较小,可以根据自己的需求进行自定义构建,但是需要花费长时间进行编译。如果不清楚编译选项,可能导致无法成功配置Code::Blocks。

目前推荐的wxWidgets的版本是2.8.7。点击此处下载wxWidgets 2.8.7源代码Windows安装包 (wxMSW-2.8.7-Setup.exe; 12.0 MB)。你也可以检查一下wxWidgets的下载页面看看有没有更新的稳定版下载。强烈建议你将代码安装到不带空格的路径中。必须保证盘中至少有300MB的剩余空间。

wxPack

虽然安装包达200MB,全部安装需要3G,但是包含了预编译的所有可能用到的库文件,而且包含VC和GCC的两种版本,可以不用去考虑构建选项了。

当前wxPack的稳定发布版是 v2.8.7.03,基于 wxWidgets 2.8.7。点击此处下载 wxPack v2.8.7.03 (wxPack_v2.8.7.03.exe, 236.9 MB)。你也可以查看wxPack下载页面看看有没有更新的稳定版下载。强烈建议将wxPack安装到没有空格的路径中。如果你选择只MSVC版本,应保证至少有700MB的剩余空间;如果只选择MinGW/GCC版本,则应保证至少有2.2GB的剩余空间。

提示

如果磁盘使用了NTFS格式,可以开启文件压缩功能,上述的目录在压缩后可以减少50%的空间占用。

编译wxWidgets

使用wxPack则可以跳过这一步。

打开命令行(在开始菜单中点击“运行”,输入cmd并回车)。如果使用的MSVC,你可以使用特定的用于设置环境变量的命令行。如果你使用的 MSVC版本还要求你单独下载Platform SDK,确保全部包含了标准编译工具和Platform SDK中要用到的环境变量。

转到wxWidgets的构建目录,其中是源码所在路径,通常是C:\wxWidgets-2.8.7

cd \build\msw

执行构建命令,MinGW/GCC推荐的命令是:

mingw32-make -f makefile.gcc BUILD=release SHARED=1 MONOLITHIC=1 UNICODE=1

MSVC推荐的构建命令是:

nmake -f makefile.vc BUILD=release SHARED=1 MONOLITHIC=1 UNICODE=1

这个过程需要花很久,快的机器大概30分钟可以完成,慢的可能就需要几个小时了。

如果使用的GCC的版本较新,构建过程中可能会出现大量的警告。这样会明显导致构建过程变慢;你可以将错误信息重定向到文件中,在上述命令后面添加2> err.log,也可以通过2>nul直接禁止警告信息。

其中关于BUILD、SHARED、MONOLITHIC以及UNICODE选项的解释,请仔细参考文章后面关于wxWidgets的构建参数的解 释,这些参数十分关键,他们直接定义了你所使用的基本的wxWidgets开发环境。你必须严格按照你的编译参数设置Code::Blocks的配置向 导。

在Code::Blocks中创建wxWidgets项目

在Code::Blocks的起始页面中,选择“Create a new project”,也可以在File菜单中,选择“New” -> “Project…”。

找到并选择“wxWidgets project”,并创建,接下来会出现一个向导帮助进行wxWidgets项目的配置:

  1. 第一个页面是简介,可以选择以后跳过。
  2. 选择你要使用的wxWidgets版本。如果你是按照本文的过程配置的,那么你应该选择“wxWidgets 2.8.x”。
  3. 设置你的项目的名字的位置。
  4. 输入作者的信息(非必要)
  5. 选择自动代码和文件生成的选项。
  6. 选择wxWidgets的位置。强烈建议在此使用全局变量:输入“$(#wx)”(不包含引号)。如果你还没定义这个全局变量,那么全局变量对话框会出现,在Base Path中,选择你的wxWidgets安装路径。其他路径可以不用填。
  7. 为你的项目选择debug/release配置。推荐至少选择debug配置。
  8. 选择你的wxWidgets构建选项。必须和你构建wxWidgets时所使用的选项一致!如果你按照本文之前的方式构建的,应该将 “wxWidgets Library Settings”下的全部三个选项选中。如果用的是wxPack,由于wxPack包含了各种不同的版本,所以你只需要选择你需要的选项。这个页面的另 一个设置和wxWidgets的构建选项没有关系,你可以按照喜好来选择。如果,出于某种原因,你想使用调试版本的wxWidgets构建,选择 “Configure Advanced options”然后在下一页选择“Use __WXDEBUG__ and Debug wxWidgets lib”。
  9. 如果需要,选择额外的库。一般应用的话应该无须选择其中任何一个。

构建并运行程序

接下来,就可以选择“Build and run”(F9)对程序进行构建并运行了。如果顺利,你的wxWidgets应用程序就会出现。如果出现了什么问题,你可以参考后面的常见问题。

wxWidgets编译选项简介

BUILD

BUILD控制wxWidgets构建调试版本(BUILD=debug)或者是发布版本(BUILD=release)。绝大多数情况下你只需要 wxWidgets的发布版本就可以了,因为你应该不想要去调试wxWidgets自身,同时你依然可以通过链接wxWidgets的发布版本来构建你自 己的程序的调试版本。

  • 调试构建wxWidgets会创建带有”d”后缀的库,例如”libwxmsw28d.a”、”wxmsw28d_gcc_custom.dll”。
  • 调试构建wxWidgets会在wxWidgets库的输出目录中创建”mswd” 或者 “mswud” 目录。
  • 发布构建wxWidgets创建的库没有”d”后缀,例如”libwxmsw28.a”、”wxmsw28_gcc_custom.dll”。
  • 发布构建wxWidgets会在wxWidgets库的输出目录中创建”msw” 或者 “mswu” 目录。

SHARED

SHARED控制wxWidgets是构建DLL(SHARED=1)还是静态库(SHARED=0)。利用构建的DLL,主程序构建时间较快,可执行文件更小。但是可执行文件加上wxWidgets DLL的总大小更大,但是不同的可执行文件可以使用同一个DLL。

  • wxWidgets的DLL构建会创建导入库(如 libwxmsw28.a)以及DLL文件(如wxmsw28_gcc_custom.dll)。你必须在发布你的程序的时候包含这个DLL。
  • wxWidgets的静态构建只会创建静态库(如 libwxmsw28.a),发布的时候也无须包含wxWidgets的DLL。

MONOLITHIC

MONOLITHIC控制是构建一个单一的库(MONOLITHIC=1)还是多个组件库(MONOLITHIC=0)。使用单一构建,项目的设置 和开发会更加简单,如果你同时使用DLL构建的话,你只需要分发一个DLL文件。如果使用非单一构建(multilib),会构建出多个不同的库同时你可 以避免将整个wxWidgets的基本代码链接到主程序,就可以去掉不需要的库。同时你也必须确保你选择了正确的组件库。

  • wxWidgets的单一构建仅会创建一个wxWidgets导入库(如libwxmsw28.a)以及一个DLL(如wxmsw28_gcc_custom.dll)。
  • wxWidgets的多库(multilib)构建会创建多个导入库(libwx28_base.a等)以及多个DLL文件。
  • 无论何种wxWidgets构建,都会创建额外的静态库(如libwxexpat.a、libwxjpeg.a等)。这些库对于wxWidgets的DLL构建一般是不需要的,但是当使用静态构建的时候,则是必须的。

UNICODE

UNICODE控制wxWidgets以及你的程序是否使用支持Unicode的宽字符串。大多数Windows 2000或更高系统上的应用程序都应该支持Unicode。早期的Windows版本不一定有Unicode支持。你应该总是使用wxWidgets的_("string")_T("string")宏来确保硬编码的字符串编译时是正确的类型。

  • wxWidgets的Unicode(UNICODE=1)构建将会创建带有”u”后缀的库,例如”libwxmsw28u.a”、”wxmsw28u_gcc_custom.dll”。
  • wxWidgets的Unicode构建会在wxWidgets库的输出目录中创建”mswu”或”mswud”目录。
  • wxWidgets的ANSI(UNICODE=0)构建创建的库没有”u”后缀,例如”libwxmsw28.a”、”wxmsw28_gcc_custom.dll”。
  • wxWidgets的ANSI构建会在wxWidgets库的输出目录中创建”msw”或”mswd”目录。

常见问题

出现类似于”wx/setup.h: No such file or directory”的错误

你在构建选项中缺少了很重要的编译器搜索路径。首先确认你是否在运行wxWidgets项目向导的时候正确选择了wxWidgets的构建配置。如果重新运行向导并配置依然无效,那么打开你的项目的构建选项并给编译起的搜索路径中添加”$(#wx.lib)\gcc_dll\mswu“(这里假设是一个单一的Unicode DLL构建)。

出现类似于”cannot find -lwxmsw28u”的错误

构建选项中的链接库错了。首先确认你是否在运行wxWidgets项目向导的时候正确选择了wxWidgets的构建配置。如果重新运行向导并配置依然无效,确定你构建了什么库,并相应在构建选项中调整库的名字。


摘自曹力的博客

http://shiningray.cn/windows-shang-pei-zhi-codeblocks-wxwidgets.html

标签: , ,

wxWidgets & Code::Blocks Studio

近来无事想写一个小程序,又不想花太多时间在UI上;就想起了一直关注的wxWidgets(以前叫wxWindows,据说是因为微软施压才改的名)。选用他的理由有三:

  1. 只会C。。。
  2. 不想因为界面设计而花太多时间
    • wxWidgets已经有了像wxGlade这样的东东,画个简单的界面什么的足够了
  3. 我的服务器已经都转换到了Linux;而桌面电脑随着时间的推移已经逐步的将常用的程序切换成了跨Windows/Linux的版本。所以学习一个跨平台的UI比较能够做到知识的保值
  4. wxWidgets中的wxString类提供了统一的一个字符串操作界面。一些常用的文本处理函数不用再创建了;这个我喜欢
  5. 开源、免费!

下一步就是选择IDE

主要焦点在MinGW Developer StudioCode::Blocks Studio这两个跨平台(都使用的是wxWidgets UI库)的免费软件之间:

  1. MinGW Developer Studio使用感觉还不错。有预编译的wxWidgets库;入门方便(编译wxWidgets库遇到的问题多多,后面慢慢讲)
  2. Code::Blocks Studio提供插件接口而且最重要的是更新快。这方面MinGW Developer Studio就差多了,活跃的开发团队是开源项目发展的关键!

当然差别还有很多。我是菜菜鸟看得到的就这些。。。

安装Code::Blocks Studio

Code::Blocks Studio现在发布的是RC2(还没有正式版)。但RC2问题多多(我发现的就有对Unicode编译的支持问题);不过有Nightly Builds可以解决。我的解决步骤是:

  1. 先下载并安装RC2整合MingW的版本,这样也就不用再去下载MingW(MingW下载包太多了,安装头痛)
  2. 下载Nightly Builds(现在登陆C::B这个论坛要注册,前几天都还可以匿名的)中的
    1. Unicode wxWidget动态支持库(新版的C::B已经使用Unicodede发布)
    2. C::B的Nightly Builds,我下的是2006/1/20号的rev1823
  3. 将两个包中文文件解压覆盖到C:\Program Files\CodeBlocks

安装wxWdigets

  1. 我在wxWidgets官方下载页面上下载的wxMSW v2.6.2 的ZIP版
  2. 解到D:\(安装完成后的路径为:D:\wxWidgets-2.6.2,之后的设置都用的是这个路径)

编译wxWdigets(支持ODBC)

  1. 首先编辑D:\wxWidgets-2.6.2\include\wx\msw\setup.h以便编译后的动/静态库文件支持ODBC(为了让编译出来的库支持ODBC,我至少编译了4次才找到原来还要在这儿修改。虽然wxWidgets的手册上写要修改setup.h不过没有具体说是那个目录下的。。。吐血)。修改内容如下:
    • 将文件中的#define wxUSE_ODBC 0修改为#define wxUSE_ODBC 1
  2. 然后我在D:\wxWidgets-2.6.2\build\msw下创建了一个envset.bat文件来设置编译需要的环境参数。
    1. 内容如下

      set PATH=%PATH%;C:\Program Files\CodeBlocks\bin;C:\Program Files\CodeBlocks\mingw32\bin;
      set LIBRARY_PATH=C:\Program Files\CodeBlocks\lib
      set C_INCLUDE_PATH=C:\Program Files\CodeBlocks\include
      set CPLUS_INCLUDE_PATH=C:\Program Files\CodeBlocks\include;D:\wxWidgets-2.6.2\include;D:\wxWidgets-2.6.2\contrib\include;

    2. 其中C:\Program Files\CodeBlocks是我的C::B的安装路径
  3. 同时修改D:\wxWidgets-2.6.2\build\msw\config.gcc
    • USE_ODBC = 0修改为USE_ODBC = 1
  4. 进入DOS命令行
  5. 切换工作路径至D:\wxWidgets-2.6.2\build\msw
  6. 运行envset.net
  7. 执行清理命令

    mingw32-make -f makefile.gcc USE_XRC=1 SHARED=1 MONOLITHIC=1 BUILD=debug UNICODE=1 clean

    • 其中
      1. SHARED=1表示生成的动态链接库DLL,0就是静态链接库
      2. MONOLITHIC=1表示生成单一的库文件,0表示生成多个按模块分割的库文件
      3. BUILD=debug表示生成带Debug信息的版本方便调试,release是发布版
      4. UNICODE=1表示使用unicode编码
  8. 执行编译命令

    mingw32-make -f makefile.gcc USE_XRC=1 SHARED=1 MONOLITHIC=1 BUILD=debug UNICODE=1 VENDOR=cb

  9. 看看电视,泡壶茶。编译的时间可不短;-)

整合C::B和wxWidgets

  1. 运行C::B。程序会提示你填写wxWidgets的安装目录
    • codeblock-wx-global-var-set.png
  2. 然后使用新建向导创建一个Using UNICODE wxWidgets DLL的wxWidgets Appliction就可以开始了
  3. codeblock-wx-create-project.png

有点晚了,关于C::B中的wxWidgets项目配置方面的改天再写。。。


http://flord.net/wxwidgets_and_codeblocks_part1

标签: , ,

wxWidgets与SlickEdit

作者:ES_ZETA
Copyright © 2006-2007 ES_ZETA
本文档由ES_ZETA独立编写并维护,如果发现错误请与我(Email:ES_ZETA@163.com)联系让我能及时修正它。欢迎广大网友提供意见。
本文档可在网络制作和发布本文档的拷贝,但在所有拷贝上要保留本版权声明和许可声明。
如果你准备出版本文档,请告之作者,以确保你获得本文档的最新版本。
对本文档的适用范围不作担保,它仅仅是作为一个免费的资源提供。因此,这里提供的这些信息的作者和维护者无法做出这些信息一定正确的保证。
最近由于工作需要,所以要开始编写Windows上的程序。考虑到以后多平台的发展方向,所以选中了wxWidgets这个多平台的GUI库,同样也选用了MinGW作为编译器。IDE则用SlickEdit,因为这个编辑器功能强大,或者可以用wxDevCpp,这个是已经集成了wxWidgets与MinGW的IDE,非常方便。
wxWidgets的安装
http://www.mingw.org 能下载最近版本的MinGW
我下载的是已经打包成EXE文件,直接点开安装到D:\MinGW下,这样MinGW就安装完成。为了以后操作方便,你可以在环境变量的PATH下加入D:\MinGW\bin。
http://www.wxwidgets.org 下载最近版本的wxWidgets。
我使用的版本为wxWidgets-2.8.0,我习惯把所有开发相关的东西都放D盘,SO,下载下来后我解压到D:/ wxWidgets-2.8.0。这个目录里只有源代码与一些例子,并没有我们需要的库。库需要重新编译生成。在目录D:\wxWidgets- 2.8.0\build下是一些文件夹(-_-!废话),不同的系统会有一个文件夹,这次是生成Windows的库所以点开msw目录,在msw下是一些 编译配置文件,从命名就可以看到不同的编译器有不同的配置文件,然后新建一个bat文件,输入

set PATH=%PATH%;d:\MinGW\bin;d:\MinGW\mingw32\bin;
set LIBRARY_PATH=d:\MinGW\lib
set C_INCLUDE_PATH=d:\MinGW\include
set CPLUS_INCLUDE_PATH=d:\MinGW\include;D:\wxWidgets-2.8.0\include;D:\wxWidgets-2.8.0\contrib\include;

这个BAT用来设置好一些编译需要的头文件与库的路径好让编译能成功完成。
我是用gcc作编译器所以点开config.gcc,里面定义了以后生成的库的一些设置,你可以直接修改里面的内容,或者在编译里以参数形式设置。我选择前者,因为我老打错字,而且以参数形式设置太麻烦了。
下面几个设置是我比较注意的,详细的设置可以看config.gcc里面的说明。
BUILD=debug
建立debug(调 试)版本的库,如果是发行版本则改为release,这个会影响库的名字(增加一个'd'),会定义__WXDEBUG__,而且调试信息也会被编译进目 标文件和执行文件里。Debug模式下编译出来的exe可是30M左右的超大包,而release则只有3M。
SHARED=0
建立静态库,而不是DLL(动态库)。我比较喜欢把所有库都连到exe中,所以我选择静态。
UNICODE=1
是否建立Unicode版本的库,需要则设置为1。如果你想在Windows9x上使用 Unicode 版本,你另外还需要设置 MSLU=1。要显示中文则一定要设置为1,并且你的源代码要以Unicode作为编码。
VENDOR=你的名字或工作室的名字
这个信息会添加到库中
CFG = 这个配置的名字
这个设置会影响生成库后存放的路径
下面开始编译我们的库:
Win+R调出“运行”,输入cmd,Win9X的话是command(很久没用9x所以忘记了),调出命令行后cd到D:\wxWidgets-2.8.0\build\msw。然后运行我们刚才建立的BAT文件。
然后输入
mingw32-make -f makefile.gcc clean
清理完后,就可以开始编译
mingw32-make -f makefile.gcc
如果你选用参数来设置的话可以这样添加到尾部
mingw32-make -f makefile.gcc BUILD=release UNICODE=1
下面就是等待,你可以去看看片或者吃个饭……
吃完饭回来后发现在我的D:\wxWidgets- 2.8.0\lib\gcc_lib多了一堆东西,这就是我们要的库。不依赖于GUI组件的库会以"wxbase"开头,紧跟着是版本号,然后的字母表明 这个库是否是编译为Unicode ('u')和/或是否编译成debug('d')。名字中的最后部分是wxWidgets组件的名字。如果是生成动态库的话,目录名会为gcc_dll。 如果你设置了CFG,则目录名会含有CFG里面的值。重复上面步骤把debug与release两个库都生成了。Debug库后面会有‘d’作为标释,以 后连接时要注意这点。而D:\wxWidgets-2.8.0\build\msw下面那个文件夹是中间文件,可以删了。
好了,wxWidgets已经编译好了。
SlickEdit的设置
好了,到了SlickEdit的设置了,这个搞了我好几天的时间来配,主要是冤枉路走得太多了,不过最后还是让我成功了。
SlickEdit是一个收费的软件,我用的版本为11.0.2。
打 开SlickEdit,File->New,点Project->Customize->New,New package name里填wxWidgets或者其它你喜欢的名字,下面Copy settings from选择GNU C/C++ Wizard。
把Settings for:设置为debug。
选中Directories把D:\wxWidgets-2.8.0\include\ 与D:\wxWidgets-2.8.0\lib\gcc_lib\mswud\添加到Includes中,我喜欢把‘.’也添加进去代表工程当前路径。
选中Tools,然后选中Build,点击Options会出现新对话框:

选中Compile:这是关于编译的设置
把NOPCH _UNICODE __WXDEBUG__ __WXMSW__ HAVE_W32API_H添加到Preprocessor Defines里,这些都是一些宏的定义。把-mthreads -Wno-ctor-dtor-privacy添加到Other Options里。这些设置会作为编译时的参数,所以要注意当中的空格。
选中Code Generation,把Produce debugging information(-g)前面勾选。Level of optimization为None,Level of debug code为Default。
选中Link:这是关于连接的设置
把-lwxmsw28ud_core -lwxbase28ud -lwxtiffd -lwxjpegd -lwxpngd -lwxzlibd -lwxregexud -lwxexpatd -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lwsock32 -lodbc32添加到Libraries,这些都是库的名字。如库文件为libXXX.a则他的库名为XXX,也就是去了头的lib与尾。-l是连接时 的参数。前面的是我编译出来的库名,不同设置编译出来的库名会有所区别,后面的那些32结尾的是MinGW的库名。开始时我没加这个,所以怎么弄都没通 过,白白花了我好几天时间。
把-mthreads -Wl,--subsystem,windows -mwindows -LD:\wxWidgets-2.8.0\lib\gcc_lib添加到Other Options里。其中-L后面的是我的库的路径,你需要按你的实况情况来设置。
Directories已经设置好了,所以选中Warnings:这是错误输出的设置
把-W与-Wall勾上,其它的按需要设置。

把Settings for:设置为release。
选中Directories:把D:\wxWidgets-2.8.0\include\ 与D:\wxWidgets-2.8.0\lib\gcc_lib\mswu\添加到Includes里。注意添加的是mswu而非debug的mswud。
同样选中Tools:
再选中Build->Options,在新对话框里设置相关的东西。

选中Compile:
把HAVE_W32API_H __WXMSW__ _UNICODE NOPCH加到Preprocessor Defines里。把-mthreads -Wno-ctor-dtor-privacy添加到Other Options。
选中Code Generation:
把Level of optimization设置为Med。把-g前面的勾去了。
选中Link:
把-lwxmsw28u_core -lwxbase28u -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lwsock32 -lodbc32加到Libraries/Objects里。
把-mthreads -Wl,-subsystem,windows -mwindows -LD:\wxWidgets-2.8.0\lib\gcc_lib加到Other Options里。同样的-L后面跟的是你的库的路径。
选中Warnings:
把-W与-Wall打开。把所有的warning messages都显示出来。

设置好了,我们可以试一下写个小DEMO了……
http://blog.donews.com/ESZETA/archive/2006/12/17/1097617.aspx

标签: , , ,

辽ICP备05003652号
流风洄雪听天籁,轻云蔽日看落花

Powered by Blogger