??xml version="1.0" encoding="utf-8" standalone="yes"?>
PS:
预编译头的概念:
所谓的预编译头是把一个工E中的那一部分代码,预先~译好放在一个文仉(通常?
?pch为扩展名?Q这个文件就UCؓ预编译头文gq些预先~译好的代码可以是Q何的
C/C++代码--------甚至是inline的函敎ͼ但是必须是稳定的Q在工程开发的q程中不?
被经常改变。如果这些代码被修改Q则需要重新编译生成预~译头文件。注意生成预~?
译头文g是很耗时间的。同时你得注意预~译头文仉常很大Q通常?-7M大。注意及
时清理那些没有用的预~译头文件?
也许你会问:现在的编译器都有Time stamp的功能,~译器在~译整个工程的时候,?
只会~译那些l过修改的文Ӟ而不会去~译那些从上ơ编译过Q到现在没有被修改过
的文件。那么ؓ什么还要预~译头文件呢Q答案在q里Q我们知道编译器是以文g为单
位编译的Q一个文件经q修改后Q会重新~译整个文gQ当然在q个文g里包含的所?
头文件中的东西(.eg Macro, Preprocesser Q都要重新处理一遍。VC的预~译头文?
保存的正是这部分信息。以避免每次都要重新处理q些头文件?
预编译头的作用:
Ҏ上文介绍Q预~译头文件的作用当然是提高便宜速度了,有了它你没有必要每次
都编译那些不需要经常改变的代码。编译性能当然提高了?
预编译头的用:
要用预~译_我们必须指定一个头文gQ这个头文g包含我们不会l常改变?
代码和其他的头文Ӟ然后我们用这个头文g来生成一个预~译头文Ӟ.pch文gQ?
惛_大家都知?StdAfx.hq个文g。很多h都认是VC提供的一?#8220;pȝU别”?
Q编译器带的一个头文g。其实不是的Q这个文件可以是M名字的。我们来考察一?
典型的由AppWizard生成的MFC Dialog Based E序的预~译头文件。(因ؓAppWizard
会ؓ我们指定好如何用预~译头文Ӟ默认的是StdAfx.hQ这是VCL名字Q。我?
会发现这个头文g里包含了以下的头文gQ?
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4
Common Controls
#include <afxcmn.h>
q些正是使用MFC的必d含的头文Ӟ当然我们不太可能在我们的工程中修改这些头?
件的Q所以说他们是稳定的?
那么我们如何指定它来生成预编译头文g。我们知道一个头文g是不能编译的。所以我
们还需要一个cpp文g来生?pch 文g。这个文仉认的是StdAfx.cpp。在q个文g
里只有一句代码就是:#include “Stdafx.h”。原因是理所当然的,我们仅仅是要它能
够编译而已?D?D?D也就是说Q要的只是它?cpp的扩展名。我们可以用/Yc~译开x?
定StdAfx.cpp来生成一?pch文gQ通过/Fp~译开x指定生成的pch文g的名字。打
开project ->Setting->C/C++ 对话框。把Category指向Precompiled Header。在左边?
树Ş视图里选择整个工程
Project Options(右下角的那个白的地方)可以看到 /Fp “debug/PCH.pch”Q这是?
定生成的.pch文g的名字,默认的通常是 <工程?gt;.pchQ我的示例工E名是PCHQ?
然后Q在左边的树形视N选择StdAfx.cpp.//q时只能选一个cpp文gQ?
q时原来的Project Option变成?Source File OptionQ原来是工程Q现在是一个文?
Q当然变了)。在q里我们可以看到 /Yc开养I/Yc的作用就是指定这个文件来创徏一?
Pch文g?Yc后面的文件名是那个包含了E_代码的头文gQ一个工E里只能有一个文
件的可以有YC开兟뀂VC根据这个选项?StdAfx.cpp~译成一个Obj文g和一个PCH文g
?
然后我们再选择一个其它的文g来看看,//其他cpp文g
在这里,Precomplier 选择?Use ⋯⋯⋯一,头文件是我们指定创徏PCH 文g的stda
fx.h
文g。事实上Q这里是使用工程里的讄Q(如图1Q?Yu”stdafx.h”?
q样Q我们就讄好了预编译头文g。也是_我们可以使用预编译头功能了。以
下是注意事项Q?
1):如果使用?YuQ就是说使用了预~译Q我们在每个.cpp文g的最开_我强调一?
是最开_包含 你指定生pch文g?h文gQ默认是stdafx.hQ不然就会有问题。如
果你没有包含q个文gQ就告诉你Unexpected file end. 如果你不是在最开头包含的Q?
你自p以下q道了Q绝Ҏ很惊人的效果?.
fatal error C1010: unexpected end of file while looking for precompiled
header directive
Generating Code...
2Q如果你把pch文g不小心丢了,~译的时候就会生很多的不正常的行ؓ。根据以?
的分析,你只要让~译器生成一个pch文g。也是说把 stdafx.cppQ即指定/Yc的那?
cpp文gQ从新编译一遍。当然你可以d?Rebuild All。简单一点就是选择那个cpp
文gQ按一下Ctrl + F7可以了。不然可是很费旉的哦?
q两天看csdn有一些关于socket_包Qsocket~冲|的问题Q发现自׃是很清楚Q所以查资料了解记录一下:
一两个单概念长q接与短q接Q?br>1.长连?/p>
Client方与Server方先建立通讯q接Q连接徏立后不断开Q?然后再进行报文发送和接收?/p>
2.短连?/p>
Client方与Server每进行一ơ报文收发交易时才进行通讯q接Q交易完毕后立即断开q接。此U方式常用于一点对多点
通讯Q比如多个Clientq接一个Server.
?什么时候需要考虑_包问题?
1:如果利用tcp每次发送数据,׃Ҏ建立q接Q然后双方发送完一D|据后Q就关闭q接Q这样就不会出现_包问题Q因为只有一U包l构,cM于http协议Q。关闭连接主要要双方都发送closeq接Q参考tcp关闭协议Q。如QA需要发送一D字W串lBQ那么A与B建立q接Q然后发送双斚w默认好的协议字符?hello give me sth abour yourself"Q然后B收到报文后,将~冲区数据接?然后关闭q接Q这L包问题不用考虑刎ͼ因ؓ大家都知道是发送一D字W?br>
2Q如果发送数据无l构Q如文g传输Q这样发送方只管发送,接收方只接收存储就okQ也不用考虑_包
3Q如果双方徏立连接,需要在q接后一D|间内发送不同结构数据,如连接后Q有好几U结构:
1)"hello give me sth abour yourself"
2)"Don't give me sth abour yourself"
那这L话,如果发送方q箋发送这个两个包出去Q接收方一ơ接收可能会?hello give me sth abour yourselfDon't give me sth abour yourself" q样接收方就MQ到底是要干嘛?不知道,因ؓ协议没有规定q么诡异的字W串Q所以要处理把它分包Q怎么分也需要双方组l一个比较好的包l构Q所以一般可能会在头加一个数据长度之cȝ包,以确保接收?br>
?_包出现原因Q在传输中出现QUDP不会出现_包Q因为它有消息边?参考Windows |络~程)
1 发送端需要等~冲区满才发送出去,造成_包
2 接收方不及时接收~冲区的包,造成多个包接?/p>
解决办法Q?br>Z避免_包现象Q可采取以下几种措施。一是对于发送方引v的粘包现象,用户可通过~程讄来避免,TCP提供了强制数据立即传送的操作指opushQTCP软g收到该操作指令后Q就立即本D|据发送出去,而不必等待发送缓冲区满;二是对于接收方引L_包Q则可通过优化E序设计、精接收q程工作量、提高接收进E优先{措施,使其及时接收数据Q从而尽量避免出现粘包现象;三是由接收方控制Q将一包数据按l构字段Qh为控制分多次接收Q然后合qӞ通过q种手段来避免粘包?/p>
以上提到的三U措施,都有其不之处。第一U编E设|方法虽然可以避免发送方引v的粘包,但它关闭了优化算法,降低了网l发送效率,影响应用E序的性能Q一般不使用。第二种Ҏ只能减少出现_包的可能性,但ƈ不能完全避免_包Q当发送频率较高时Q或׃|络H发可能使某个时间段数据包到达接收方较快Q接收方q是有可能来不及接收Q从而导致粘包。第三种Ҏ虽然避免了粘包,但应用程序的效率较低Q对实时应用的场合不适合?/p>
解决_包问题Q?a >http://www.vckbase.com/document/viewdoc/?id=1203
在socket 文g传输中,获取某个目录下的所有文Ӟ如果一个文件名传输一ơ通讯的话Q?27.0.0.1上测试没有什么问题,当在局域网中传?ơ以上,׃出现包丢失问题。我猜这个问题跟_包有点怼?
?/span>Win7旗舰版下使用VS2008~译E序时出?/span>LINK : fatal error LNK1000: Internal error during IncrBuildImage错有如下两种解决ҎQ?/span>
Ҏ一Q打补丁
到微软网站下?/span>343461_ENU_i386_zip补丁包,然后打补丁既可?/span>
Ҏ二:修改目讄
目->属?/span>->链接?/span>->常规 下面?#8220;启用增量链接”Q将“?/span>(/INCREMENTAL)”改ؓ“?/span>(/INCREMENTAL:NO)”既可?br>
psQ找不到补丁包,按W二U方法?/span>
1 htons
htons(1986)得到的结果是49671
如何得到49671q个l果?
1986转换?6q制?7C2
L序转换成网l顺序之后是C207
C207转换为十q制?9671
例子:0x12 34 56 78l过htons?x78 56 34 12
在给SOCKADDR_INl构中的端口L接赋?客户端和服务端全部都直接赋?br style="line-height: 22px; ">SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = 1986;
q样也可以通讯,但绑定的端口号已l不?986,而是49671
2 INADDR_ANY
#define INADDR_ANY (u_long)0x00000000
INADDR_ANY表示 所有的IP,如果自己的主机有多个IP,在给SOCKADDR_IN l构的IP地址赋值时qINADDR_ANY.
如果只有一个IP且是固定?也可以不用INADDR_ANY,使用如下语句
addrSrv.sin_addr.S_un.S_addr = inet_addr("221.217.218.111");
inet_addr函数是将一个点分十q制的IP转换成无W号长整?/p>
3 SOCKADDR_INl构
struct sockaddr_in
{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
sin_family:|络cd
sin_port:|络端口?br style="line-height: 22px; ">in_addr:IP地址
sin_zero:保证l构的大?br style="line-height: 22px; ">in_addr的结构ؓ
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
对于IP地址?21.217.218.111,addrSrv.sin_addr.S_un的赋值方法如?br style="line-height: 22px; ">W一U?
addrSrv.sin_addr.S_un.S_addr =111<<24|218<<16|217<<8|221;
W二U?
addrSrv.sin_addr.S_un.S_addr =htonl(221<<24|217<<16|218<<8|111);
W三U?
addrSrv.sin_addr.S_un.S_addr = inet_addr("221.217.218.111");
W四U?
addrSrv.sin_addr .S_un.S_un_w.s_w1 =217<<8|221;
addrSrv.sin_addr .S_un.S_un_w.s_w2 =111<<8|218;
W五U?
addrSrv.sin_addr .S_un.S_un_b.s_b1=221;
addrSrv.sin_addr .S_un.S_un_b.s_b2=217;
addrSrv.sin_addr .S_un.S_un_b.s_b3=218;
addrSrv.sin_addr .S_un.S_un_b.s_b4=111;
DWORD dwSize;
CHAR szHead[] = "Accept: */*\r\n\r\n";
VOID* szTemp[16384];
HINTERNET hConnect;
CFile file;
if ( !(hConnect = InternetOpenUrlA ( hOpen, szUrl, szHead,
lstrlenA (szHead), INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0)))
{
AfxMessageBox("不能打开该URL!");
return -1;
}
if (file.Open(szFileName,CFile::modeWrite|CFile::modeCreate)==FALSE )
{
AfxMessageBox("不能打开本地的文?");
return -1;
}
DWORD dwByteToRead = 0;
DWORD dwSizeOfRq = 4;
DWORD dwBytes = 0;
if (!HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
(LPVOID)&dwByteToRead, &dwSizeOfRq, NULL))
{
dwByteToRead = 0;
}
DWORD start;
DWORD end;
DWORD time;
CString tempstring;
time = 10;
start = timeGetTime();
do
{
if (!InternetReadFile (hConnect, szTemp, 16384, &dwSize))
{
AfxMessageBox("L件出?");
file.Close();
return -1;
}
if (dwSize==0)
break;
else
file.Write(szTemp,dwSize);
dwBytes+=dwSize;
if(dwByteToRead)
{
tempstring.Format("%d%%",(dwBytes*100)/dwByteToRead);
SetDlgItemText(IDC_PERCENT_TEXT,tempstring);
}
FLOAT fSpeed = 0;
fSpeed = (float)dwBytes;
fSpeed /= ((float)time)/1000.0f;
fSpeed /= 1024.0f;
tempstring.Format("%dKB/s",fSpeed);
SetDlgItemText(IDC_SPEED_TEXT,tempstring);
end = timeGetTime();
time = end - start;
if(time == 0)
time = 10;
}while (TRUE);
file.Close();
InternetCloseHandle(hOpen);
一 WinINet是微软开发的一个库Q可以完成http ftp客户端的工作。让E序员从复杂的协议中节省大量体力?/p>
?我会用了http, ftpcM。用WinINet完成一个http下蝲需要以下步??下面q个是同步操作(也就是一步步操作Q每个函数执行完才会q回一个结果的意思)
1 InternetOpen Initializes an application's use of the WinINet functions.
需要的?InternetSetOption 讄代理服务器地址以及端口?br> httpQ?nbsp; ip:port 或?http=http://ip:port
socksQSOCKS=ip:port
2 InternetConnect 兌目标地址或者域名以及服务ip
3 HttpOpenRequest 兌要下载的内容名字
InternetSetOption 讄用户名密?/p>
4 HttpSendRequest q步是用HttpOpenRequest 的返回|已经兌了上面的所有信息)发送出去,W一ơ用了网l。向目标服务器或者代理服务器?/p>
5 HttpQueryInfo
该函数查询返回|不参与网l操作。可以查询服务器的返回信息,比如目标文g的大,该文件是否存在,代理服务q回了要求用户名Q密码等{(q几个最常用Q,q有很多信息?/p>
6 InternetReadFile
很普通的d敎ͼ是下蝲文g。不知道是否和底层网l同步,底层会不会提前下载呢Q?/p>
7 InternetCloseHandle 释放资源
?nbsp; 异步操作Q比较复杂的?nbsp; Z么需要异步操作呢Q?因ؓ涉及到网l操作,某些函数在操作中可能需要时_如果一直不q回Q比?U)Ӟq时ȝE要l束E序Q岂不就出现意想不到的结果了Q但是如果每个函数都能够瞬间q回Q然后通过WaitForMultipleObjects或者WaitForSingleObject{待l果的出玎ͼ此时׃会操作那个消?U的函数了,而这?U函数正是要用到pȝ资源HINTERNET的)?/p>
异步操作的目的上如,原理呢? 其实原理是注册一个函敎ͼ在这里叫InternetStatusCallbackQ因为微软写得底层代码要用到Q所以必L式统一。一旦有l果来了通过事g通知我们QWaitForSingleObject函数可以走了。比如等CHINTERNET创徏或者命令发送成功等l果。然后我们就可以W一旉安全的用了?br> API 函数如果名字最后可以带EXQ那么带ex的就是异步操作的?/p>
?一定要注意Q凡是有unicode和mutilbyte函数的一定要l一Q最好都用mutilbyte的?/p>
五: 代码如下Q?br>// crt_assert.c
// compile with: /c
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <iostream>
#include "winsock2.h"
#include <string>
#include <Wininet.h>
#include <windows.h>
#include <fstream> //要用文件输入输出流必须的头文g
using namespace std;
#define __HTTP_VERB_GET "GET"
#define __HTTP_VERB_POST "POST"
#define __HTTP_ACCEPT_TYPE "*/*"
#define __HTTP_ACCEPT "Accept: */*\r\n"
#define __SIZE_HTTP_BUFFER 100000
#define __SIZE_HTTP_RESPONSE_BUFFER 100000
#define __SIZE_HTTP_HEAD_LINE 2048
void CALLBACK InternetStatusCallback(
HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength);
HANDLE hEvent[3];
HINTERNET hFile;
HINTERNET hNet;
HINTERNET hSession,hConnect,hRequest;
int WaitExitEvent()
{
//return 1;
DWORD dwRet = ::WaitForMultipleObjects(3, hEvent, FALSE, 30000);//INFINITE);
int x=-1;
switch (dwRet)
{
//句柄被创Z件或者读数据h成功完成事g
case WAIT_OBJECT_0:
x=0;
cout<<"WAIT_OBJECT_0"<<endl;
//句柄被关闭事?br> break;
case WAIT_OBJECT_0+1:
x=1;
cout<<"WAIT_OBJECT_1"<<endl;
//用户要求l止子线E事件或者发生错误事?br> break;
case WAIT_OBJECT_0+2:
x=2;
cout<<"WAIT_OBJECT_2"<<endl;
break;
default:
cout<<"WaitForMultipleObjects time out"<<endl;
return -1;
}
return x;
}
// 支持代理讄Q?是否异步讄Q?采用事g驱动
void WinINet3(bool setProxy, bool ASYNC)
{
hSession=NULL;
hConnect=NULL;
hRequest=NULL;
for (int i = 0; i < 3; i++)
{
hEvent[i] = CreateEvent(
NULL, // default security attributes
FALSE, // auto-reset event object
FALSE, // initial state is nonsignaled
NULL); // unnamed object
if (hEvent[i] == NULL)
{
printf("CreateEvent error: %d\n", GetLastError() );
ExitProcess(0);
}
}
char *url = " char *pip = "down.360safe.com";
char *paim = "/setup.exe";
// step 1
if(ASYNC) cout<<"异步模式"<<endl;
// setProxy =false;
if(setProxy)
{
cout<<"代理模式"<<endl;
if(ASYNC)
hSession = InternetOpen("name",
INTERNET_OPEN_TYPE_DIRECT,//|INTERNET_OPEN_TYPE_PROXY,// INTERNET_OPEN_TYPE_PROXY,
NULL,NULL,INTERNET_FLAG_ASYNC); // 异步
else
hSession = InternetOpen("name",INTERNET_OPEN_TYPE_PROXY,NULL,NULL,0); // 同步
}
else
{
if(ASYNC)
hSession = InternetOpen("name",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,INTERNET_FLAG_ASYNC); // 异步
else
hSession = InternetOpen("name",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); // 同步
}
if(!hSession){
DWORD er = ::GetLastError();
cout<<"InternetOpen error"<<endl;//, "Err", MB_OK);
return;
}
if(ASYNC)
{
//Sleep(500);
INTERNET_STATUS_CALLBACK res = ::InternetSetStatusCallback(hSession,InternetStatusCallback);
if(res == INTERNET_INVALID_STATUS_CALLBACK)
{
cout<<"InternetSetStatusCallback failed, so return "<<endl;
return ;
}
else
{
cout<<"InternetSetStatusCallback succeed, so go on "<<endl;
}
//Sleep(500);
}
char strProxyList[MAX_PATH], strUsername[64], strPassword[64];
strcpy(strProxyList, "SOCKS=58.56.87.2:1080"); // 写上socks怎么无效了呢?Q?SOCKS5=172.18.132.27:1080
strcpy(strUsername, "user01");
strcpy(strPassword, "baidu");
INTERNET_PROXY_INFO proxy;
proxy.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
proxy.lpszProxy = strProxyList;
proxy.lpszProxyBypass = NULL;
if( setProxy &&!InternetSetOption(hSession,INTERNET_OPTION_PROXY ,&proxy,sizeof(INTERNET_PROXY_INFO)))
{
cout<<"InternetSetOption failed"<<endl;
return ;
}
// step 2
//如果明确知道需要认证,W?Q?个参数可以输入用户名Q密?administrator","password"
//W?Q?个参Cؓ目标LIP、端口号(不是代理服务器的参数)
hConnect = InternetConnect(hSession,pip,INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,INTERNET_FLAG_RELOAD,0);
if(!ASYNC &&!hConnect){
cout<<"同步QInternetConnect error"<<endl;//, "Err", MB_OK);
return;
}
if( ASYNC&& hConnect== NULL)// 异步 需要等?nbsp; 竟然直接创徏好了
{
int er = GetLastError();
DWORD dwError = ::GetLastError();
if (dwError != ERROR_IO_PENDING)
{
cout<<"CHttpDownload::OpenInternetConnection| q接p|" <<endl;
return ;
}
else //
{
cout<<"hConnect == NULL, so run WaitExitEvent"<<endl;
WaitExitEvent(); // {待成功创徏 // q里应该{待 q里应该昄一ơ呀
::ResetEvent(hEvent[0]);
::ResetEvent(hEvent[1]);
::ResetEvent(hEvent[2]);
}
}
cout<<"step 2 :InternetConnect secced"<<endl;
// ::InternetSetStatusCallback(hConnect,InternetStatusCallback);
// step 3!!!
char szHead[] = "Accept: */*\r\n\r\n";
char **p = new char*[2];*p = szHead;*(p+1) = NULL;
//hRequest = HttpOpenRequest(hConnect,"GET","download/BaiduHi_1.0_Beta2.exe",NULL,NULL,/*(const char **)p*/NULL,0/*INTERNET_FLAG_NO_COOKIES|INTERNET_FLAG_RELOAD*/,0); // no request;
CONST TCHAR *szAcceptType=__HTTP_ACCEPT_TYPE;
hRequest = ::HttpOpenRequest(hConnect,
"GET",
paim,
HTTP_VERSION,
"",
&szAcceptType,
INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_CACHE_WRITE,
0);
//::HttpAddRequestHeaders( hRequest, __HTTP_ACCEPT, strlen(__HTTP_ACCEPT), HTTP_ADDREQ_FLAG_REPLACE);
/*_hHTTPRequest=::HttpOpenRequest( _hHTTPConnection,
__HTTP_VERB_GET, // HTTP Verb
szURI, // Object Name
HTTP_VERSION, // Version
"", // Reference
&szAcceptType, // Accept Type
INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE,
0); // context call-back point
*/
if (!ASYNC&& !hRequest){
cout<<"同步QHttpOpenRequest error"<<endl;//, "Err", MB_OK);
return;
}
if( ASYNC&& hRequest== NULL)// 异步 需要等?br> {
int er = GetLastError();
DWORD dwError = ::GetLastError();
if (dwError != ERROR_IO_PENDING)
{
cout<<"CHttpDownload::OpenInternetConnection| q接p|" <<endl;
return ;
}
else //
{
cout<<"hRequest == NULL, so run WaitExitEvent"<<endl;
WaitExitEvent(); // {待成功创徏
::ResetEvent(hEvent[0]);
::ResetEvent(hEvent[1]);
::ResetEvent(hEvent[2]);
}
}
//Sleep(10000);
cout << "step 3 : HttpOpenRequest success"<<endl;
//::InternetSetStatusCallback(hRequest,InternetStatusCallback);
//////////////////////////////////////////////
if (setProxy )
{
// InternetSetOption 不要异步{待
if( !InternetSetOption(hRequest,INTERNET_OPTION_PROXY_USERNAME ,strUsername,strlen(strUsername)+1))
{
cout<<"InternetSetOption Username failed"<<endl;
return ;
}
if( !InternetSetOption(hRequest,INTERNET_OPTION_PROXY_PASSWORD ,strPassword,strlen(strPassword)+1))
{
cout<<"InternetSetOption Password failed"<<endl;
return ;
}
}
// step 4
//HttpSendRequest(hRequest,NULL,0,NULL,0);
//Sleep(3000);
::ResetEvent(hEvent[0]);
::ResetEvent(hEvent[1]);
::ResetEvent(hEvent[2]);
if(!::HttpSendRequest(hRequest,NULL,0,NULL,0)) // Z么失败?Q?
{
//Sleep(3000);
if(!ASYNC)// 同步
{
DWORD dwError = ::GetLastError();
cout<<"同步QHttpSendRequest failed, GetLastError=="<<dwError<<endl;
return ;
}
else
{
Sleep(3000);
DWORD dwError = ::GetLastError();
cout<<"dwError =="<<dwError<<endl;
if (dwError != ERROR_IO_PENDING)
{
cout<<"dwError != ERROR_IO_PENDING, so quit,dwError =="<<dwError<<endl;
return ;
}
else //
{
cout<<"HttpSendRequest, so run WaitExitEvent"<<endl;
Sleep(3000);
//if(WaitExitEvent()!=2)//; // {待成功创徏 {待是否不对Q?Q?br> {
cout<<"had not recv complete event, so quit"<<endl;
// return ;
}
}
}
}
Sleep(3000);
cout << "step 4: HttpSendRequest success!"<<endl;
int bufh[1000];
DWORD dwLen,dwIndex;
/*if(!::HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, bufh, &dwLen, &dwIndex))// q句话?Q?
{
//return E_FAIL;
return;
}
*/
// 判断状态码Q?br> char m_dwStatusCode[90];
DWORD dwStatusSize = sizeof(m_dwStatusCode);
/*if (FALSE == ::HttpQueryInfo(hRequest, // 查询失效Q?
HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
&m_dwStatusCode,
&dwStatusSize,
NULL)) //获取q回状态码
{
return ;
}
//判断状态码是不?200
//if (HTTP_STATUS_OK != m_dwStatusCode)
{
//return ;
}
*/
DWORD dwByteToRead = 0;
DWORD dwSizeOfRq = 4;
DWORD dwBytes = 0;
//q三个值分别存储文件的大小QHttpQueryInfo内容的大和dd的字节数?br> //HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwByteToRead, &dwSizeOfRq, NULL);
//需要说明的?HttpQueryInfo q不q行|络操作Q因此它不需要进行异步操作的处理?
if (!HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwByteToRead, &dwSizeOfRq, NULL))
{ // q里p|了?Q?
DWORD dwError = ::GetLastError();
cout<<"HttpQueryInfo failed, so returnQ?GetLastError() =="<<dwError<<endl;
return ;
}
FILE * pFile = fopen("e://baidu01.exe", "wb" );
//ofstream mfile("out.txt");//定义文g输出oufQƈ兌到out.txt
int i=0;
DWORD leftB = dwByteToRead;
cout<<"开始下?<<endl;
if( !ASYNC) // 同步下蝲
{
while(true)
{
const int MAX_BUFFER_SIZE = 65536;
unsigned long nSize = 0;
char szBuffer[MAX_BUFFER_SIZE+2];
int num = MAX_BUFFER_SIZE;
if( leftB < num);
num = leftB;
BOOL bRet = ::InternetReadFile(hRequest, szBuffer, num, &nSize); // 异步 需要等?/p>
leftB -= nSize;
cout<<i++<<" size: "<<nSize<<endl;
if(!bRet || nSize <= 0)
break;
fwrite(szBuffer, sizeof(char), nSize, pFile);
}
}
else // 异步下蝲
{
INTERNET_BUFFERS i_buf = {0};
i_buf.dwStructSize = sizeof(INTERNET_BUFFERS);
i_buf.lpvBuffer = new TCHAR[10242];
i_buf.dwBufferLength = 10240;
for( DWORD i=0;i<dwByteToRead;)
{
//重置L据事?br> ::ResetEvent( hEvent[0]);
int num = 10240;
if(dwByteToRead-i<10240)
{
num = dwByteToRead-i;
i_buf.dwBufferLength = dwByteToRead-i;
}
if (FALSE == ::InternetReadFileEx(hRequest,
&i_buf,
IRF_ASYNC,
NULL))
{
if (ERROR_IO_PENDING == ::GetLastError())
{
if ( NULL)//WaitExitEvent()!=2)
{
delete[] i_buf.lpvBuffer;
return ;
}
}
else
{
cout<<"down failed,so return"<<endl;
delete[] i_buf.lpvBuffer;
return ;
}
}
else
{
//在网l传输速度快,步长较小的情况下Q?br> //InternetReadFileEx l常会直接返回成功,
//因此要判断是否发生了用户要求l止子线E事件?br> cout<<"|络很好QInternetReadFileExq回true"<<endl;
// 暂不考虑用户退?br> }
i += i_buf.dwBufferLength; // 最后一ơ写多了Q!Q?br> fwrite(i_buf.lpvBuffer, sizeof(char), i_buf.dwBufferLength, pFile);
cout<<"i== "<<i<<endl;
//保存数据
//通知ȝE下载进?br>
}
}
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
cout<<"success download file"<<endl;
return;
}
int main( void )
{
WinINet3(true,true);
return 1;
}
void OnInternetHandleCreated(HINTERNET hInternet, LPINTERNET_ASYNC_RESULT lpInetStatusResult)
{
if(NULL == lpInetStatusResult)
{
//ATLASSERT( 0 );
return;
}
hFile = HINTERNET(lpInetStatusResult->dwResult);
HINTERNET hInet = HINTERNET(lpInetStatusResult->dwResult);
DWORD dwInetHandleType;
DWORD dwTypeLen = sizeof(dwInetHandleType);
InternetQueryOption( hInet, INTERNET_OPTION_HANDLE_TYPE, &dwInetHandleType, &dwTypeLen);
switch(dwInetHandleType)
{
case INTERNET_HANDLE_TYPE_CONNECT_HTTP:
//CloseInternetConnection(); // q里是何意?Q?Q?通过回调 讄httpConnect
hConnect = hInet; //
break;
case INTERNET_HANDLE_TYPE_HTTP_REQUEST:
//CloseInternetFile(); // q里是何意?Q?nbsp; 通过回调 讄httpFile
hRequest = hInet; //
break;
default:
break;
}
cout<<"OnInternetHandleCreated, so ::SetEvent(hEvent[0])"<<endl;
// HANDLE已创ZӞ异步控制Q?br> ::SetEvent(hEvent[0]);
}
void OnInternetRequestComplete(HINTERNET hInternet, LPINTERNET_ASYNC_RESULT lpInetStatusResult)
{
if( lpInetStatusResult == NULL )
{
//ATLASSERT( 0 );
return;
}
cout<<"OnInternetRequestComplete, so ::SetEvent(hEvent[2])"<<endl;
// Ȁ发请求完成事Ӟ异步控制Q?br> ::SetEvent(hEvent[0]);
}
void CALLBACK InternetStatusCallback(
HINTERNET hInternet,
DWORD_PTR dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength
)
{
cout<<"q入回调"<<endl;
switch (dwInternetStatus)
{
case INTERNET_STATUS_RESOLVING_NAME:
break;
case INTERNET_STATUS_NAME_RESOLVED:
break;
case INTERNET_STATUS_CONNECTING_TO_SERVER:
break;
case INTERNET_STATUS_CONNECTED_TO_SERVER:
break;
case INTERNET_STATUS_SENDING_REQUEST:
break;
case INTERNET_STATUS_REQUEST_SENT:
break;
case INTERNET_STATUS_RECEIVING_RESPONSE:
break;
case INTERNET_STATUS_RESPONSE_RECEIVED:
break;
case INTERNET_STATUS_CLOSING_CONNECTION:
break;
case INTERNET_STATUS_CONNECTION_CLOSED:
break;
case INTERNET_STATUS_HANDLE_CREATED:
cout<<"回调是INTERNET_STATUS_HANDLE_CREATED"<<endl;
OnInternetHandleCreated(hInternet, LPINTERNET_ASYNC_RESULT(lpvStatusInformation)); // 传递了HINTERNET q是_N呀
break;
case INTERNET_STATUS_HANDLE_CLOSING:
break;
case INTERNET_STATUS_REQUEST_COMPLETE:
cout<<"回调是INTERNET_STATUS_REQUEST_COMPLETE"<<endl;
OnInternetRequestComplete(hInternet, LPINTERNET_ASYNC_RESULT(lpvStatusInformation));
break;
case INTERNET_STATUS_REDIRECT:
case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
case INTERNET_STATUS_STATE_CHANGE:
default:
break;
}
}
CRect BoxRect;
BoxRect=rect;
BoxRect.right =BoxRect.left +15;
dc.DrawFrameControl(BoxRect,DFC_BUTTON,DFCS_BUTTONCHECK|GetCheck()?DFCS_CHECKED :0);
CFont myFont;
myFont.CreatePointFont (100,_T("宋体"));
CFont *pOldFont=(CFont *)dc.SelectObject(&myFont);
dc.SetBkMode(TRANSPARENT);
CString StrWndText;
GetWindowText(StrWndText);
rect.OffsetRect (20,0);
dc.SetTextColor(RGB(0,0,0));
dc.DrawText(StrWndText, rect, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
dc.SelectObject (pOldFont);
myFont.DeleteObject ();
}
正规软gl常用到临时文gQ你l常可以会看到C:\Windows\Temp目录下有大量的扩展名为tmp的文Ӟq些是E序q行是徏立的临时文g。时文件的使用Ҏ基本与常规文件一P只是文g名应该调用函数GetTempFileName()获得。它的第一个参数是建立此时文件的路径Q第二个参数是徏立时文件名的前~Q第四个参数用于得到建立的时文件名。得到此临时文g名以后,你就可以用它来徏立ƈ操作文g了,如:
char szTempPath[_MAX_PATH],szTempfile[_MAX_PATH];
GetTempPath(_MAX_PATH, szTempPath);
GetTempFileName(szTempPath,_T ("my_"),0,szTempfile);
CFile m_tempFile(szTempfile,CFile:: modeCreate|CFile:: modeWrite);
char m_char='a';
m_tempFile.Write(&m_char,2);
m_tempFile.Close();
5Q文件的复制、删除等
MFC中没有提供直接进行这些操作的功能Q因而要使用SDK。SDK中的文g相关函数常用的有CopyFile()、CreateDirectory()、DeleteFile()、MoveFile()。它们的用法很简单,可参考MSDN?
1,判断文g是否存在
access(filename,mode);
2,对于不同用途又不同的文件操?其中API函数CreateFile()也是比较有用处理方式,对于巨型文g很合适的其他的楼上的大都说了,不重复了.
[1]昄对话框,取得文g?/p>
CString FilePathName;
CFileDialog dlg(TRUE);///TRUE为OPEN对话框,FALSE为S***E AS对话?br>if (dlg.DoModal() == IDOK)
FilePathName=dlg.GetPathName();
相关信息QCFileDialog 用于取文件名的几个成员函敎ͼ
假如选择的文件是C:\WINDOWS\TEST.EXE
?1)GetPathName();取文件名全称Q包括完整\径。取回C:\WINDOWS\TEST.EXE
(2)GetFileTitle();取文件全名:TEST.EXE
(3)GetFileName();取回TEST
(4)GetFileExt();取扩展名EXE
[2]打开文g
CFile file("C:\HELLO.TXT",CFile::modeRead);//只读方式打开
//CFile::modeRead可改?CFile::modeWrite(只写),
//CFile::modeReadWrite(d),CFile::modeCreate(新徏)
例子Q?br>{
CFile file;
file.Open("C:\HELLO.TXT",CFile::modeCreate|Cfile::modeWrite);
.
.
.
}
[3]Ud文g指针
file.Seek(100,CFile::begin);///从文件头开始往下移?00字节
file.Seek(-50,CFile::end);///从文件末־上移?0字节
file.Seek(-30,CFile::current);///从当前位|往上移?0字节
file.SeekToBegin();///Ud文g?br>file.SeekToEnd();///Ud文g?/p>
[4]d文g
LӞ
char buffer[1000];
file.Read(buffer,1000);
写文Ӟ
CString string("自强不息");
file.Write(string,8);
[5]关闭文g
file.Close();
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/zhuang_rui/archive/2007/09/28/1804875.aspx
在MFCcd提供?strong>CWnd::OnCtlColor函数,在工作框架的子窗口被重画时将调用该成员函?因此可以重蝲WM_CTLCOLOR消息的响应函?此函数的原型:
afx_msg
HBRUSH OnCtlColor(CDC *pDC,CWnd *pWnd,UINT nCtlColor);
参数nCtlColor用于指定控g的类?可以?
.CTLCOLOR_BTN 按钮控g
.CTLCOLOR_DLG
对话?br> .CTLCOLOR_EDIT
~辑?br> .CTLCOLOR_LISTBOX 列表控g
.CTLCOLOR_MSGBOX
消息控g
.CTLCOLOR_SCROLLBAR 滚动条控?br>
.CTLCOLOR_STATIC
静态控?br>[E序实现]
假设你已有了名ؓMy的对话框工程.你有了一?strong>STATIC的控ӞID?strong>IDC_STATIC1.
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the
DC here
if (nCtlColor==CTLCOLOR_STATIC)
{
pDC->SetTextColor(RGB(255,0,0)); //字体颜色
pDC->SetBkColor(RGB(0, 0,
255)); //字体背景?/font>
}
//
TODO: Return a different brush if the default is not
desired
return hbr;
}
如果要指定某个特定控件可以这样写Q?strong>ID为IDC_STATIC1
if (pWnd->GetDlgCtrlID()==IDC_STATIC1)
{
pDC->SetTextColor(RGB(255,0,0)); //讄字体颜色
pDC->SetBkMode(TRANSPARENT); //讄字体背景为透明
//
TODO: Return a different brush if the default is not
desired
return (HBRUSH)::GetStockObject(BLACK_BRUSH); //
讄背景?br>}
else
return hbr;
【注?/strong>
BLACK_BRUSH:黑色
WHITE_BRUSH:白色
GRAY_BRUSH:灰色
NULL_BRUSH:透明
HOLLOW_BRUSH Q透明
注:如果在窗体中使用q种ҎQ会引v代码的臃肿,自定义自qcR?/span>
Windows Template Library - WTL的安装指南满地都是,而且源程序也附带了安装说明,g没有必要再多写一个。但是,事情q没有想象的那么单,本h有过近4q的C++开发经验,在两q前刚{入C#Q有很长旉没碰C++了(最后用的工具是VC++6.0Q。今天突发兴,惌玩玩VC++ 2005和WTLQ谁知,以我q种l验Q折腾这看是单的玩意Q也׃大半天的旉Ҏ搞出W一个WTL的Hello WorldQ个中曲折,说来实在惭愧Q只好把正确的安装过E写一下,如果能给别h一ҎC,那是最好的了。至,可以做个W记Q两三年以后如果又忘了,q可以回来翻R?/font>
1、从http://sourceforge.net/projects/wtl下蝲最新版本的WTLQ当时是8.0
2、下载得到的是一个自解压文gQ可以解压到L目录。比如d:\wtl80Q下面有几个子目录samples, include, AppWizMobile, AppWizCE, AppWizQ还有一个txt文g和htm文g。其中include是头文gQsamples是几个示例,AppWiz*是各U向导文件?br>3、在命o行里执行Qwscript.exe "D:\WTL80\AppWiz\setup80.js"Q如果是vs2005 express、vs2003{,分别执行setup80x.js, setup70.js,可以看看里面的文档说明?br> 注:q是一个很Ҏ让h困惑的地方,|上的文档全都说解压后执行setup80.js文gQ但都没说如何执行。后来在代码里看到有WScriptQ才惛_用WSCript.exe来执行?/font>
4、打开VS2005, 选择VC++目Q就可以看到WTL目的向g?/font>
5、在VS2005里,打开菜单“工具”——选项——项目和解决Ҏ——VC++目录Q在“昄以下内容的目?#8221;下拉框中Q选择“包含文g”Q加入刚才解压的wtl下的includeQ本例中?d:\wtl80\include"?/font>
6、按照向导创Z个程序,~译Q执行,OK?/font>
用向导徏立一个Win32E序“hello, world!”Q然后用下面的内Ҏ换整个CPP文g内容可以了
#include "stdafx.h"
#include "resource.h"
#include "ShellApi.h"
HINSTANCE hInst = NULL;
HDESK hDesktopCurrent;
HDESK hDesktopLlx;
LONG APIENTRY WndProc(
HWND hWnd,
UINT message, // type of message
WPARAM wParam, // additional information
LPARAM lParam) // additional information
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
//DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
//DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
/*
case WM_DESTROY:
PostQuitMessage(0);
break;
//*/
case WM_LBUTTONDOWN:
break;
case WM_HOTKEY:
if(7777 == wParam)
{
PostQuitMessage(0);
}
else if(7778 == wParam)
{
SwitchDesktop(hDesktopCurrent);
}
else if(7779 == wParam)
{
SwitchDesktop(hDesktopLlx);
}
break;
case WM_QUIT:
case WM_DESTROY:
SwitchDesktop(hDesktopCurrent);
return DefWindowProc(hWnd, message, wParam, lParam);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void StartMyExplore(void)
{
STARTUPINFO sui; // Process startup info
PROCESS_INFORMATION pi; // info returned from CreateProcess
//
// Most sui members will be 0
//
ZeroMemory ((PVOID)&sui, sizeof(sui));
sui.cb = sizeof (sui);
//
// Need the lpDesktop member so the new process runs on this desktop
// The lpDesktop member was reserved in previous versions of NT
//
sui.lpDesktop = _T("llx");
CreateProcess (NULL, // image name
"explorer", // command line
NULL, // process security attributes
NULL, // thread security attributes
TRUE, // inherit handles
CREATE_DEFAULT_ERROR_MODE|CREATE_SEPARATE_WOW_VDM,
NULL, // environment block
NULL, // current directory
&sui, // STARTUPINFO
&pi); // PROCESS_INFORMATION
}
int CALLBACK WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, "IDI_SETTHREADDESKTOP");
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "lilinxiang";
if(!RegisterClass(&wc))
{
return TRUE;
}
hDesktopCurrent = NULL;
hDesktopCurrent = GetThreadDesktop(GetCurrentThreadId());
hDesktopLlx = NULL;
hDesktopLlx = OpenDesktop("llx", 0, FALSE, NULL);
if (hDesktopLlx != NULL)
{
CloseDesktop(hDesktopLlx);
}
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
hDesktopLlx = CreateDesktop("llx", NULL,
NULL,0,MAXIMUM_ALLOWED,
NULL);
if(hDesktopLlx == NULL)
{
return 0;
}
if(!SetThreadDesktop(hDesktopLlx))
{
char szError[256] = {0};
ltoa( (long)(GetLastError()) , szError, 10);
}
SwitchDesktop(hDesktopLlx);
HWND hWnd = NULL;
hWnd = CreateWindow ("lilinxiang",
"hello, world!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
NULL
);
if(NULL == hWnd)
{
return TRUE;
}
//register hotkey for exit this desktop or switch to another desktop
//ShowWindow(hWnd, SW_SHOW);
//UpdateWindow(hWnd);
if(!RegisterHotKey(hWnd, 7777, MOD_CONTROL, 'Q'))
{//exit process
return TRUE;
}
if(!RegisterHotKey(hWnd, 7778, MOD_CONTROL | MOD_SHIFT, 'Q'))
{//switch to new desktop
return TRUE;
}
if(!RegisterHotKey(hWnd, 7779, MOD_CONTROL | MOD_SHIFT, 'W'))
{//switch to original desktop
return TRUE;
}
StartMyExplore();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);// Translates virtual key codes
DispatchMessage(&msg); // Dispatches message to window
}
SwitchDesktop(hDesktopCurrent);
return TRUE;
}
// : ) 好东西噢
用CreateDesktop新徏一个桌面,什么都没有的桌面,然后在新桌面环境中运行了explorer所以就有了和windows一样功能的桌面Q这个时候你有了两个桌面了Q下面要做的是用SwitchDesktop切换不同的桌面了
在不同桌面中打开的程序在其他桌面的Q务栏包括pȝ托盘上不可见Q不qQ务管理器中还是可见的q样你就非常方便的做很多事了Q很?.. 而且q可以非常快的{到正常状态上可以让会责骂你的人比如老板什么的无话可说Q因Z们什么也看不?nbsp; : )
或者你也可以给你用户定制一个个性化的桌面。改改上面的代码可以得到你要的效果的?/p>
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/goingup/archive/2006/03/07/618323.aspx用向导徏立一个Win32E序“hello, world!”Q然后用下面的内Ҏ换整个CPP文g内容可以了
#include "stdafx.h"
#include "resource.h"
#include "ShellApi.h"
HINSTANCE hInst = NULL;
HDESK hDesktopCurrent;
HDESK hDesktopLlx;
LONG APIENTRY WndProc(
HWND hWnd,
UINT message, // type of message
WPARAM wParam, // additional information
LPARAM lParam) // additional information
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
//DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
//DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
/*
case WM_DESTROY:
PostQuitMessage(0);
break;
//*/
case WM_LBUTTONDOWN:
break;
case WM_HOTKEY:
if(7777 == wParam)
{
PostQuitMessage(0);
}
else if(7778 == wParam)
{
SwitchDesktop(hDesktopCurrent);
}
else if(7779 == wParam)
{
SwitchDesktop(hDesktopLlx);
}
break;
case WM_QUIT:
case WM_DESTROY:
SwitchDesktop(hDesktopCurrent);
return DefWindowProc(hWnd, message, wParam, lParam);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void StartMyExplore(void)
{
STARTUPINFO sui; // Process startup info
PROCESS_INFORMATION pi; // info returned from CreateProcess
//
// Most sui members will be 0
//
ZeroMemory ((PVOID)&sui, sizeof(sui));
sui.cb = sizeof (sui);
//
// Need the lpDesktop member so the new process runs on this desktop
// The lpDesktop member was reserved in previous versions of NT
//
sui.lpDesktop = _T("llx");
CreateProcess (NULL, // image name
"explorer", // command line
NULL, // process security attributes
NULL, // thread security attributes
TRUE, // inherit handles
CREATE_DEFAULT_ERROR_MODE|CREATE_SEPARATE_WOW_VDM,
NULL, // environment block
NULL, // current directory
&sui, // STARTUPINFO
&pi); // PROCESS_INFORMATION
}
int CALLBACK WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, "IDI_SETTHREADDESKTOP");
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "lilinxiang";
if(!RegisterClass(&wc))
{
return TRUE;
}
hDesktopCurrent = NULL;
hDesktopCurrent = GetThreadDesktop(GetCurrentThreadId());
hDesktopLlx = NULL;
hDesktopLlx = OpenDesktop("llx", 0, FALSE, NULL);
if (hDesktopLlx != NULL)
{
CloseDesktop(hDesktopLlx);
}
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
hDesktopLlx = CreateDesktop("llx", NULL,
NULL,0,MAXIMUM_ALLOWED,
NULL);
if(hDesktopLlx == NULL)
{
return 0;
}
if(!SetThreadDesktop(hDesktopLlx))
{
char szError[256] = {0};
ltoa( (long)(GetLastError()) , szError, 10);
}
SwitchDesktop(hDesktopLlx);
HWND hWnd = NULL;
hWnd = CreateWindow ("lilinxiang",
"hello, world!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
NULL
);
if(NULL == hWnd)
{
return TRUE;
}
//register hotkey for exit this desktop or switch to another desktop
//ShowWindow(hWnd, SW_SHOW);
//UpdateWindow(hWnd);
if(!RegisterHotKey(hWnd, 7777, MOD_CONTROL, 'Q'))
{//exit process
return TRUE;
}
if(!RegisterHotKey(hWnd, 7778, MOD_CONTROL | MOD_SHIFT, 'Q'))
{//switch to new desktop
return TRUE;
}
if(!RegisterHotKey(hWnd, 7779, MOD_CONTROL | MOD_SHIFT, 'W'))
{//switch to original desktop
return TRUE;
}
StartMyExplore();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);// Translates virtual key codes
DispatchMessage(&msg); // Dispatches message to window
}
SwitchDesktop(hDesktopCurrent);
return TRUE;
}
// : ) 好东西噢
用CreateDesktop新徏一个桌面,什么都没有的桌面,然后在新桌面环境中运行了explorer所以就有了和windows一样功能的桌面Q这个时候你有了两个桌面了Q下面要做的是用SwitchDesktop切换不同的桌面了
在不同桌面中打开的程序在其他桌面的Q务栏包括pȝ托盘上不可见Q不qQ务管理器中还是可见的q样你就非常方便的做很多事了Q很?.. 而且q可以非常快的{到正常状态上可以让会责骂你的人比如老板什么的无话可说Q因Z们什么也看不?nbsp; : )
或者你也可以给你用户定制一个个性化的桌面。改改上面的代码可以得到你要的效果的?/font>
The WM_NCLBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.
使用WM_NCLBUTTONDOWN 消息Q?br>利用标题栏的消息Q欺骗windows使得点击客户区可实现H体的移动。在打击客户区的时候假传消息给windowsQ告诉他现在左击标题栏?br>class A
{
public:
virtual void FA() = 0;
};
class B
{
public:
virtual void FB() = 0;
};
class C : public A , public B
{
public:
void FA(){cout<<"FA"<<endl;}
void FB(){cout<<"FB"<<endl;}
};
int main()
{
C* mc = new C();
B* mb = static_cast<B*>(mc);
((A*)mb)->FA();
return 0;
}
输出的是FB, com中利用这机制实现了聚合?/p>
按OK后,如果马上~译的话会出现如下错误:
LIBCMTD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/Dll.dll : fatal error LNK1120: 1 unresolved externals
打开VC++菜单Project\Settings\C/C++选项卡,如下图,在Project OptionsQ末地方d”/D”Q图中蓝色高亮的地方Q,要注意位|,我试了,要把/D攑ֈ/GZ后面也会链接错误Q我也不懂ؓ什么,^_^。按OKQ再ơ编译,成功。大家可以自己测试下到底有没有更Ҏ功,什么,如果试Q打式信息啊?/p>
1.4 DisableThreadLibraryCalls
看帮助就知道它是q么用的Q?br>The DisableThreadLibraryCalls function disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the dynamic-link library (DLL) specified by hLibModule. This can reduce the size of the working code set for some applications.
原文地址Q?a >http://www.blogjava.net/Yipak/articles/182025.html
int __stdcall Sub(int numa, int numb)
{
return (numa - numb);
}
然后创徏一?def的文Ӟ在里面加?br>
;DllTestDef.lib : 导出DLL函数
;作者:----
LIBRARY defDll.dll
EXPORTS
Add @ 1
Sub @ 2
最后创Z个测试程序:.cpp文g如下Q?br>#include <iostream>
#include <windows.h>
using namespace std;
typedef int (__stdcall *Fun)(int , int);
HINSTANCE hInstance;
Fun fun;
int main()
{
hInstance = LoadLibrary("defDll.dll");
if (!hInstance)
cout<<"Not Find this Dll"<<endl;
fun = (Fun)GetProcAddress(hInstance, MAKEINTRESOURCE(1));
cout<<fun(12,3)<<endl;;
fun = (Fun)GetProcAddress(hInstance, "Sub");
cout<<fun(7, 3)<<endl;
FreeLibrary(hInstance);
}
msdn中:
Handle to a bitmap.typedef HANDLE HBITMAP;
cbitmap是mfc中封装bitmap的类Q?/p>
msdn中:
EncapsulatesQ囊括) a Windows graphics device interface (GDI) bitmap and provides member functions to manipulateQ操作) the bitmap.
class CBitmap : public CGdiObject转化Ҏ两种Q?br>Attach和FromHandleQ?br>CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
HBITMAP hbm = (HBITMAP)bmp;
CBitmap bmp1;
bmp1.Attach(hbm);
HBITMAP = CBitmap.m_hObject;
CBitmap* = CBitmap.FromHandle(HBITMAP)//已知
HBITMAP hbit;
CBitmap cb;
cb.FromHandle(hbit);//已知
CBitmap cb;
HBITMAP hbit=(HBITMAP)cb;
CBitmap bmp;HBITMAP hBmp;
怺转换QhBmp=(HBITMAP)bmp.GetSafeHandle();bmp.Attach(hBmp);
注意点:Attach和FromHandle的区别FromHandle得到的指针是临时变量Q?通过Attachq接的句柄可以长久保?但通过FromHandle得到的只是暂时的,大概只在一个消息区间内有效,很快便会被删?所以基本上不能用。我用了FromHandle然后一直出错!Q!
CBitmap 无法从文件中加蝲位图Q可以用下面的方法解冟?/p>
HBITMAP hBitmap;
//hBitmap = (HBITMAP)::LoadImage(::AfxGetInstanceHandle(), "NetFriend.bmp", IMAGE_BITMAP, 0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);//从文件中加蝲Q?br> hBitmap = (HBITMAP)::LoadImage(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0,0,LR_CREATEDIBSECTION);//从资源文件中加蝲
MFC 消息控制最L色的地方是CWndcȝ虚拟函数PreTranslateMessage()Q通过重蝲q个函数Q可以改变MFC的消息控制流E,甚至可以作一个全新的控制出来。只有穿q消息队列的消息才受PreTranslateMessage()影响Q采用SendMessage()或其他类似的方式向窗口直接发送的而不l过消息队列的消息根本不会理睬PreTranslateMessage()的存在?nbsp;
是否调用TranslateMessage()和DispatchMessage()是由一个名UCؓPreTranslateMessage()函数的返回值决定的Q如果该函数q回TRUEQ则不会把该消息分发l窗口函数处理?
传给PreTranslateMessage()的消息是未经译q的消息Q它没有l过TranslateMessage()处理。可以在该函C使用(pMsg->wParam==VK_RETURN)来拦截回车键。wParam中存攄是键盘上字符的虚拟码?
PeekMessage和GetMessage的区别:
GetMessage在没有消息的时候等待消息,cpu当然?
PeekMessage没有消息的时候立刻返回,所以cpu占用率高?
因ؓ游戏不能靠windows消息驱动Q所以要用PeekMessage();
PretranslateMessage 的实玎ͼ不得不谈到MFC消息循环的实现。MFC通过CWinAppcM的Pumpmessage函数实现消息循环Q但是实际的消息循环代码位于 CWinThread中,CWinApp只是从CWinThreadl承q来。其化后的代码大概如下:
BOOL CWinThread::PumpMessage()
{
_AFX_THREAD_STATE *pState = AfxGetThreadState();
::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL))
if (!AfxPreTranslateMessage(&(pState->m_msgCur)))
{
::TranslateMessage(&(pState->m_msgCur));
::DispatchMessage(&(pState->m_msgCur));
}
return TRUE;
}
可以看到QPumpMessage在实际的TranslateMessage和DispatchMessage发生之前会调?AfxPreTranslateMessageQAfxPreTranslateMessage又会调用 CWnd::WalkPreTranslateTree(虽然也会调用其他函数Q但是这个最为关键)Q其代码如下Q?
BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg)
{
ASSERT(hWndStop == NULL || ::IsWindow(hWndStop));
ASSERT(pMsg != NULL);
// walk from the target window up to the hWndStop window checking
// if any window wants to translate this message
for (HWND hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
{
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
if (pWnd != NULL)
{
// target window is a C window
if (pWnd->PreTranslateMessage(pMsg))
return TRUE; // trapped by target window (eg: accelerators)
}
// got to hWndStop window without interest
if (hWnd == hWndStop)
break;
}
return FALSE; // no special processing
}
可以看到Q代码还是很直接的。从接受到消息的H口层层往上遍历,q调用PretranslateMessage看是否返回TRUEQ是则结束,否则l箋?
q里有一个地斚w常关键:CWnd *pWnd = CWnd::FromHandlePermanent(hWnd) q一句代码从当前AfxModuleThreadState拿到Permanent句柄表,从而找到hWnd对应的CWnd
MFC 中PreTranslateMessage是GetMessage(...)函数的下一U操作,即GetMessage(...)从消息队列中获取消息后,交由PreTranslateMessageQ)处理Q若其返回FALSE则再交给TranslateMessage?DispatchMessage处理Q进入WindowProcQ;
如果用SendMessage, 则消息直接交到WindowProc处理Q所以GetMessage不会取得SendMessage的消息,当然PreTranslateMessage也就不会被调用?nbsp; [Page]
如果用PostMessage,则消息进入消息队列,由GetMessage取得QPreTranslateMessage有Zq行处理?
例子Q?br>按Enter,ESC按是不会退Z
BOOL CComboBoxExDlg::PreTranslateMessage(MSG* pMsg)
{
if(WM_KEYDOWN == pMsg->message )
{
UINT nKey = (int) pMsg->wParam;
if( VK_RETURN == nKey || VK_ESCAPE == nKey )
return TRUE ;
}
return CDialog::PreTranslateMessage(pMsg);
}
~辑框,如何响应的这个回车的信息
如果你的~辑框定义如?
CEdidt m_cName; //ID号ؓIDC_E_NAME
BOOL CSecondDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call class
if (pMsg->message==WM_KEYDOWN)
{
//CWnd *p=GetDlgItem(IDC_E_NAME);
CWnd * hWnd=GetFocus();
//if(pMsg->wParam==13 && pMsg->hwnd==m_cName)
if(pMsg->wParam==13 && hWnd==&m_cName)
{
处理函数
return TRUE;
}
else
{
处理函数
}
}
return CDialog::PreTranslateMessage(pMsg);
}