??xml version="1.0" encoding="utf-8" standalone="yes"?>
问题原因Q出C隐式重复定义。exe 和DLL中重复定义_iob
解决办法Q编译工E都讄成DEBUG MTD(Multi-threaded Debug DLL (/MDd))Quse MFSas static library )
环境QDL(VS2005Q?exe (VC6.0,VS2005)
]]>
串口一?Pin,q_较常用的是RS232,TX 和RX,做开关用的时候用到DTR 和RTS,一般是W四和第七Pin.
在打开串口的时候必Enable DTR和RTS?br>
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl= RTS_CONTROL_ENABLE;
DTRQRTS Pin 在串口开和关的时候电压分别ؓ正负11 ? 如此可以做两个开兛_现四U状态?
]]>
HANDLE hFile= CreateFile(L"\\123.txt",, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING FILE_ATTRIBUTE_NORMAL, NULL);
...
HANDLE hMapFile =CreateFileMapping( hFile, NULL, PAGE_READWRITE, 0,100, NULL);
if (hMapFile == NULL) {
printf("hMapFile is NULL: last error: %d\n", GetLastError() );
return (2);
}
....
CloseHandle(hFile);
CloseHandle(hMapFile);
错误代码 6Q?#8220;句柄无效”Q调试检查hFile 句柄Q确实有效?br>
在PC上工作正常的代码Q移植到PDA上会出现q个问题Q相当的隑֏人,唯一的在一个E文网站看C文章有说到QCE,和PPC上不能用CreateFile()得到的句柄作为CreateFileMapping()的输入,该怎么解决却没有看C文?br>
问题先放在这了,如果有高手遇到过cM问题Q请不吝指教Q留下脚印?br>
仔细看MSDNQ原来是自己把自q忽悠了,上面明明写了要用CreateFileForMapping()来得到句柄,自己一直没有小心看.
In both Release and debug 模式,hPreInstance每次都会得到0X00000000,q不因ؓ有另外一个实体的存在而得到别的输?但是CreateMutex()可以侦测到是不是W一个实?
不知道是我理解的不对q是q种说法有误Q?br>那么QCreateMutex() 又是怎么来实现的呢?
有点断章取义了,文章后面有说刎ͼ
"以上情况在Windows NT和Windows 95 中略有变化由于Win32 E式的每个执行实?都有自己的地址I间,q一个视H类别已l不可能,hPreInstance 永远为零?
int main(int argc, char* argv[])
{
int countx = 0,
x=9991;
char szBinary[64]={0};
printf("please input an int data\n",countx);
scanf("%d",&x);
itoa(x,szBinary,2);
printf("x=%d\t%s\n",x,szBinary);
while(x)
{
countx ++;
x = x&(x-1);
itoa(x,szBinary,2);
printf("x=%d\t%s\n",x,szBinary);
}
printf("countx=%d\n",countx);
system("pause");
// printf("press any key to quit\n",countx);
return 0;
}
法固然?但是不很直观?br>其实我觉得只要{化成字符串之?直接N?1"字符可以了,同样的扩展性更?可以转化成随意进?N意数字的个数 .
Hook | Scope |
---|---|
WH_CALLWNDPROC | Thread or global |
WH_CALLWNDPROCRET | Thread or global |
WH_CBT | Thread or global |
WH_DEBUG | Thread or global |
WH_FOREGROUNDIDLE | Thread or global |
WH_GETMESSAGE | Thread or global |
WH_JOURNALPLAYBACK | Global only |
WH_JOURNALRECORD | Global only |
WH_KEYBOARD | Thread or global |
WH_KEYBOARD_LL | Global only |
WH_MOUSE | Thread or global |
WH_MOUSE_LL | Global only |
WH_MSGFILTER | Thread or global |
WH_SHELL | Thread or global |
WH_SYSMSGFILTER | Global only |
HWND hWndDesk;
HDC hdc,hdcmem;//hdc1,
BITMAP bm;
HBITMAP hOldBmp;
HPEN hPen;
HANDLE hBitmapImag;
TCHAR szTemp[MAX_PATH]={0};
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
char* cpText ="在桌面输ZE?; //要显C的字符?nbsp;
hWndDesk=GetDesktopWindow();
if(hWndDesk==NULL)
MessageBox(NULL,"GetDesktopWindow() fail",NULL,0);
hPen=CreatePen(PS_SOLID,20,RGB(255,0,0));
if(hPen==NULL) MessageBox(NULL,"CreatePen() fail",NULL,0);
//hdc1=GetDC(hWndDesk);
hdc=GetWindowDC(hWndDesk); //hdc1 hdc 的结果不一P句柄不一P使用hdc1昄没有效?原因GetDC()得到的只是客户区的句?而GetWindowDC()得到的是包括非客户区的整个窗口的句柄,你可以在标题栏操?br> //GetWindowText(hWndDesk,szTemp,MAX_PATH);
TextOut(hdc,100,100, cpText, strlen(cpText)); //在桌面上昄字符?nbsp;
hBitmapImag=(HBITMAP)LoadImage(NULL,TEXT("c:\\pic.bmp"),IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
if(!hBitmapImag) MessageBox(NULL,TEXT("LoadImage() fail"),NULL,0);
GetObject( hBitmapImag, sizeof( BITMAP), (LPVOID)&bm);
hdcmem=CreateCompatibleDC(hdc);
hOldBmp =(HBITMAP)SelectObject(hdcmem,hBitmapImag);
BitBlt(hdc,100,100,bm.bmWidth,bm.bmHeight,hdcmem,0,0,SRCCOPY);
SelectObject(hdc, hOldBmp);
DeleteObject(hPen);
ReleaseDC(hWndDesk, hdc);
return 0;
}
HANDLE hProcess=INVALID_HANDLE_VALUE;
HANDLE hSnapshot=INVALID_HANDLE_VALUE;
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 pe;
Process32First(hSnapshot,&pe);
do
{
// do what you want
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pe.th32ProcessID);
if(hProcess==NULL) {
_stprintf(szTemp,"OpenProcess() fail\n %d\n%s",GetLastError(),pe.szExeFile);
wsprintf(szExePath,_T("%s"),"not get Process handle OpenProcess()");
}else if(0==GetModuleFileNameEx((HINSTANCE)hProcess,NULL,szExePath,MAX_PATH))
{
_stprintf(szTemp,"GetModuleFileName() fail %d\n%s\n%s",GetLastError(),pe.szExeFile,szExePath);
wsprintf(szExePath,_T("%s"),"not get Process handle GetModuleFileName()");
}
}
while(Process32Next(hSnapshot,&pe));
CloseHandle(hSnapshot);
OpenProcess() 错误ERROR CODE 5:拒绝讉K.需要取得相应的权限.
OpenProcessToken函数的功能是打开一个与一q程相联pȝ讉K令牌(access token)Q它的原型如下:
BOOL OpenProcessToken(
HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle
);
如同MSDN上所_对于Windows XP ProfessionalQ如果一台计机加入C个工作组中,而且"Force network logons using local accounts to authenticate as Guest"的限制被Ȁzȝ话,此函Cp|?
另外Q如果在调用的时候用了TOKEN_ALL_ACCESShQ函C可能会失败。这是因为TOKEN_ALL_ACCESS可能包含了TOKEN_ADJUST_SESSIONIDQ在Winnt.h中被定义Q。TOKEN_ADJUST_SESSIONID是一个新的访问maskQ是在Windows 2000和Windows XP中新增的。在Windows NT 4.0中,讉K令牌的访问控制列表中是没有这个值的。所以,如果一个应用程序是使用新的Platform SDK中的Winnt.h但却在Windows NT 4.0下运行的话,在调用OpenProcessToken()或者OpenThreadToken时指定了TOKEN_ALL_ACCESS的话Q函C会失败(使用GetLastError()q回的是ERROR_ACCESS_DENIED)?/u>
typedef struct _TOKEN_PRIVILEGES {
DWORD PrivilegeCount;
LUID_AND_ATTRIBUTES PrivilegeCount;
LUID_AND_ATTRIBUTES Privileges[]; } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle, // handle to token
BOOL TokenHandle, // handle to token
BOOL DisableAllPrivileges, // disabling option
PTOKEN_PRIVILEGES NewState, // privilege information
DWORD NewState, // privilege information
DWORD BufferLength, // size of buffer
PTOKEN_PRIVILEGES PreviousState, // original state buffer
PDWORD PreviousState, // original state buffer
PDWORD ReturnLength // required buffer size
);
在枚举所有进E之前获取操作权?可以避免出错的问题,当然参数要设|ؓEnable.
BOOL ProcessPrivilege(BOOL bEnable)
{
BOOL bResult = TRUE;
HANDLE hToken=INVALID_HANDLE_VALUE;
TOKEN_PRIVILEGES TokenPrivileges;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken) == 0)
{
printf("OpenProcessToken Error: %d\n",GetLastError());
bResult = FALSE;
}
TokenPrivileges.PrivilegeCount = 1;
TokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&TokenPrivileges.Privileges[0].Luid);
AdjustTokenPrivileges(hToken,FALSE,&TokenPrivileges,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
if(GetLastError() != ERROR_SUCCESS)
{
bResult = FALSE;
}
CloseHandle(hToken);
return bResult;
}
nRet=ReadFile(hFile,buffer,dwNeedRead,&dwRead,NULL);
if(!nRet){
MessageBox("ReadFile() fail","Error",0);
CloseHandle(hFile);
return;
}
memcpy(wchbuffer,buffer,1024);
_tsetlocale(LC_ALL,_T(""));//讄代码?br> nRet=wcstombs(chbuffer,wchbuffer,sizeof(wchbuffer));
if(nRet==1) {
sprintf(chmsg,"wcstombs changed :%d Error:%d",nRet,GetLastError());
MessageBox(chmsg,"debug",0);
}
要读所有内容的话,q需要处理?/p>
#include <windows.h>
WINDOWS.H是主要的含入档案Q它包含了其他Windows表头档案Q这些表头档案的某些也包含了其他表头档案。这些表头档案中最重要的和最基本的是Q?br>WINDEF.H 基本型态定义?br>WINNT.H 支援Unicode的型态定义?br>WINBASE.H Kernel函式?br>WINUSER.H 使用者介面函式?br>WINGDI.H 囑Ş装置介面函式?br>q些表头档案定义了Windows的所有资料型态、函式呼叫、资料结构和常数识别字,它们是Windows文g中的一个重要部分?/font>
函数调用规则指的是调用者和被调用函数间传递参数及q回参数的方法,常用的有PascalQ?stdcallQcdecl.
__cdecl C调用规则Q?/p>
Q.在后面的参数先进入堆栈;
Q.在函数返回后Q调用者要负责清除堆栈Q所以这U调用常会生成较大的可执行程序.
__stdcall 又称为WINAPIQ?其调用规则:
Q.在后面的参数先进入堆栈;
Q.被调用的函数在返回前自行清理堆栈Q所以生成的代码比cdecl.
Pascal 调用规则Q?/p>
Qascal调用规则主要用在案DQNQ6函数库中Q现在基本不用.
Q.参数在前的先q入堆栈Q?/p>
Q.不支持可变参数的函数调用Q?/p>
switch(message){
case WM_CREATE:
hpenDot = CreatePen(PS_DOT, 2, RGB(255, 0, 0)); //创徏虚线ȝ
hFont=CreateFont( // Create Font
15, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("Arial")); // lpszFacename
break;
case WM_COMMAND:
break; // do nothing
case WM_PAINT:
SetWindowText(hWnd,"Text test");
hdc = BeginPaint(hWnd, &ps);
if(NULL==SelectObject(hdc,hFont))
MessageBox(NULL,"fail font","debug",0);
if(NULL==SelectObject(hdc,hpenDot))
MessageBox(NULL,"fail pen","debug",0);
GetClientRect(hWnd, &rt);
_stprintf(szMsg,"((%d,%d),(%d,%d))",rt.left,rt.top,rt.right,rt.bottom);
//SetBkColor(hdc,RGB(255,0,0));
// DrawText(hdc, szMsg, strlen(szMsg), &rt, DT_CENTER);
TextOut(hdc,10,10,szMsg,strlen(szMsg));
Rectangle(hdc,100, 100, 550,250);
EndPaint(hWnd, &ps);
UpdateWindow(ghWnd);
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return DefWindowProc(hWnd,message,wParam,lParam);
}
EVC 版:
LRESULT CALLBACK DlgProc_Panel(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
static HDC hdc;
static PAINTSTRUCT ps;
static RECT rt;
static HBRUSH hBrush;
static COLORREF wColor=RGB(0,0,0);
static int nDrawTimes=0;
static HFONT hFont;
static LOGFONT m_logfnt;
TCHAR lfFaceName[32]= TEXT("Times New Roman");
m_logfnt.lfCharSet=DEFAULT_CHARSET;
m_logfnt.lfClipPrecision=CLIP_DEFAULT_PRECIS;
m_logfnt.lfEscapement=0;
m_logfnt.lfHeight=80;
m_logfnt.lfItalic=false;
m_logfnt.lfOrientation=0;
m_logfnt.lfPitchAndFamily=FF_SWISS;
m_logfnt.lfQuality=DEFAULT_QUALITY;
m_logfnt.lfStrikeOut=false;
m_logfnt.lfUnderline=true;
m_logfnt.lfWeight=800;
m_logfnt.lfWidth=20;
m_logfnt.lfOutPrecision=OUT_DEFAULT_PRECIS;
switch (message)
{
case WM_INITDIALOG:
hFont=CreateFontIndirect(&m_logfnt);
nDrawTimes=0;
wColor=RGB(255,0,0);
MoveWindowFullScreen(hDlg);
break;
case WM_PAINT:
hdc = BeginPaint(hDlg, &ps);
GetClientRect(hDlg, &rt);
hBrush=CreateSolidBrush(wColor);
FillRect(hdc,&rt,hBrush);
//TextOut(hdc, rt.left+10, rt.top+100, "Test", 4);
SelectObject(hdc,hFont);
SetTextColor(hdc,RGB(0,0,255));
rt.top += rt.bottom/2;
DrawText(hdc,TEXT("Test\n"),-1,&rt,DT_CENTER);
DeleteObject(hBrush);
EndPaint(hDlg, &ps);
break;
case WM_LBUTTONDOWN:
case WM_KEYUP:
InvalidateRect(hDlg,&rt,TRUE);
EndDialog(hDlg,TRUE);
break;
}
return FALSE;
}
enum Win32Type{
Win32s,
WinNT3,
Win95,
Win98,
WinME,
WinNT4,
Win2000,
WinXP
};
Win32Type IsShellType()
{
Win32Type ShellType;
DWORD winVer;
OSVERSIONINFO *osvi;
winVer=GetVersion();
dwMajorVersion=(DWORD)(LOBYTE(LOWORD(winVer)));
dwMinorVersion=(DWORD)(HIBYTE(LOWORD)(winVer)));
if(winVer<0x80000000){/*NT */
ShellType=WinNT3;
osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
if (osvi!=NULL){
memset(osvi,0,sizeof(OSVERSIONINFO));
osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(osvi);
if(osvi->dwMajorVersion==4L)ShellType=WinNT4;
else if(osvi->dwMajorVersion==5L&&osvi->dwMinorVersion==0L)ShellType=Win2000; //version 5.0
else if(osvi->dwMajorVersion==5L&&osvi->dwMinorVersion==1L)ShellType=WinXP; //version 5.1
free(osvi);
}
}
else if (LOBYTE(LOWORD(winVer))<4)
ShellType=Win32s;
else{
ShellType=Win95;
osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
if (osvi!=NULL){
memset(osvi,0,sizeof(OSVERSIONINFO));
osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(osvi);
if(osvi->dwMajorVersion==4L&&osvi->dwMinorVersion==10L)ShellType=Win98;
else if(osvi->dwMajorVersion==4L&&osvi->dwMinorVersion==90L)ShellType=WinME;
free(osvi);
}
}
return ShellType;
}
VC6.0 Windows XP SP2 q行正常
在控制别的应用程序的时候,l常需要等待直到某个功能结束,例如:
打开一个窗?/span>-->{待直到H口l束 Q?/span>q个时候就可以用到SendMessage
如果在打开q个H口后仍焉要对该窗口的界面q行讄Q比?/span>Edit?/span>value{等,比如Q?/span>
打开一个窗?/span>-->控制H口?/span>control的属?/span>
q个时候就需?/span>PostMessage
使用一个钩子程序截h息后,使用SendMessage把消息发送到d理程序进行处?/span>,但是在主处理E序q没有完成Q务的时?/span>,被设|钩子的E序q入了停止的状?/span>,不可以处?WM_PAINT, WM_MOVE, .......{的基本信息, 必须要等SendMessage发送出的消息完成后,才能l箋q行,整个界面一片空?/span>,把钩子消息设|成PostMessage的发送消息Ş式后,问题解决!
PostMessage只是把消息放入队列,不管其他E序是否处理都返回,然后l箋执行;
?/span>SendMessage必须{待其他E序处理消息后才q回Ql执行?/span>
PostMessage的返回DC?/span>PostMessage函数执行是否正确;
?/span>SendMessage的返回DC其他程序处理消息后的返回倹{?/span>
使用q两个发送消息函数的最重要的是要看你的E序是否要对消息的滞后性关注否,PostMessage会造成消息的滞后?/span>,?/span>SendMessage则不?/span>,但如
if(!m_dcMemory.CreateCompatibleDC(NULL)) // CDC m_dcMemory; { ::PostQuitMessage(0); }
2)、创Z图:CreateCompatibleBitmap()
m_Bmp.CreateCompatibleBitmap(&m_dcMemory, rt.Width(), rt.Height()); // CBitmap m_Bmp;
3)、把位图选入讑֤环境QSelectObject()Q可以理解ؓ选择d
::SelectObject(m_dcMemory.GetSafeHdc(), m_Bmp);
4)、把l制好的囑Ş“拯“到屏q上QBitBlt()
pdcView->BitBlt(0, 0, rt.Width(), rt.Height(), &m_dcMemory, 0, 0, SRCCOPY);
函数的具体用法详?MSDN。有一句话我重复了多遍Q再说一遍也无妨QMSDN是最好的老师?br>
2 SM_CLEANBOOT q回pȝ启动方式:
0 正常启动
1 安全模式启动
2 |络安全模式启动
3 SM_CMONITORS CEpȝ昄模块的个?(CE>=4.0)
4 SM_CMOUSEBUTTONS q回gؓpȝ支持的鼠标键敎ͼq回0Q则pȝ中没有安装鼠标?/p>
5 SM_CXBORDER, SM_CYBORDER q回以相素gؓ单位的WindowsH口Ҏ的宽度和高度Q如果Windows的ؓ3D形态,则等同于SM_CXEDGE参数
6 SM_CXCURSOR,SM_CYCURSOR q回以相素gؓ单位的标准光标的宽度和高?/p>
7 SM_CXDLGFRAME,SM_CYDLGFRAME {同与SM_CXFIXEDFRAME and SM_CYFIXEDFRAME
8 SM_CXDOUBLECLK,SM_CYDOUBLECLK 以相素gؓ单位的双L效的矩Ş区域
9 SM_CXEDGE,SM_CYEDGE 以相素gؓ单位?DҎ的宽度和高度
10 SM_CXFIXEDFRAME,SM_CYFIXEDFRAME 围绕h标题但无法改变尺寸的H口Q通常是一些对?br>
框)的边框的厚度
11 SM_CXFRAME,SM_CYFRAME {同于SM_CXSIZEFRAME and SM_CYSIZEFRAME
12 SM_CXFULLSCREEN,SM_CYFULLSCREEN 全屏q窗口的H口区域的宽度和高度
13 SM_CXHSCROLL,SM_CYHSCROLL 水^滚动条的高度和水qx动条上箭头的宽度
14 SM_CXHTHUMB 以相素ؓ单位的水qx动条上的滑动块宽?/p>
15 SM_CXICON,SM_CYICON pȝ~省的图标的高度和宽度(一般ؓ32*32Q?/p>
16 SM_CXICONSPACING,SM_CYICONSPACING 以大图标方式查看Item时图标之间的间距Q这个距?br>
L大于{于SM_CXICON 和SM_CYICON.
17 SM_CXMAXIMIZED,SM_CYMAXIMIZED 处于层的最大化H口的缺省尺?/p>
18 SM_CXMAXTRACK,SM_CYMAXTRACK h可改变尺寸边框和标题栏的H口的缺省最大尺寸,如果H?br>
口大于这个尺寸,H口是不可移动的?/p>
19 SM_CXMENUCHECK,SM_CYMENUCHECK 以相素ؓ单位计算的菜单选中标记位图的尺?/p>
20 SM_CXMENUSIZE,SM_CYMENUSIZE 以相素计的菜单栏按钮的寸
20 SM_CXMIN,SM_CYMIN H口所能达到的最尺?/p>
21 SM_CXMINIMIZED,SM_CYMINIMIZED 正常的最化H口的尺?/p>
22 SM_CXMINTRACK,SM_CYMINTRACK 最跟t距,当用者拖动窗口移动距d于这个|
H口不会Ud?/p>
23 SM_CXSCREEN,SM_CYSCREEN 以相素ؓ单位计算的屏q尺寸?/p>
24 SM_CXSIZE,SM_CYSIZE 以相素计的标题栏按钮的寸
25 SM_CXSIZEFRAME,SM_CYSIZEFRAME 围绕可改变大的H口的边框的厚度
26 SM_CXSMICON,SM_CYSMICON 以相素计的图标的寸Q小图标一般出现在H口标题栏上?/p>
27 M_CXVSCROLL,SM_CYVSCROLL 以相素计的垂直滚动条的宽度和垂直滚动条上箭头的高度
28 SM_CYCAPTION 以相素计的普通窗口标题的高度
29 SM_CYMENU 以相素计的单个菜单条的高度
30 SM_CYSMCAPTION 以相素计的H口标题栏的高?/p>
31 SM_CYVTHUMB 以相素计的垂直滚动条中滚动块的高度
32 SM_DBCSENABLED 如果为TRUE或不?的D明系l安装了双字节版本的USER.EXE,为FALSE?
则不是?/p>
33 SM_DEBUG 如果为TRUE或不?的D明系l安装了debug版本的USER.EXE,为FALSE?则不是?/p>
34 SM_MENUDROPALIGNMENT 如果为TRUE或不?的g拉菜单是叛_齐的否则是左寚w的?/p>
35 SM_MOUSEPRESENT 如果为TRUE或不?的值则安装了鼠标,否则没有安装?/p>
36 SM_MOUSEWHEELPRESENT 如果为TRUE或不?的值则安装了滚轮鼠标,否则没有安装?Windows NT only)
37 SM_SWAPBUTTON 如果为TRUE或不?的值则鼠标左右键交换,否则没有?/p>
SendMessage( (HWND) hWnd, // handle to destination window WM_SETFONT, // message to send (WPARAM) wParam, // handle to font (LPARAM) lParam // redraw option );MSDN 里面SendMessage() 里面使用WM_SETFONT参数 wParam 必须使用自己定义的FONT的句柄,而不是?FONT 定义的内宏V所以错误发生在Q?br>(WPARAM)(&ResultFont) 而应该?(WPARAM)(&ResultFont)->GetSafeHandle()?br>
其格式一般是Q?#pragma paramenter
其中Q?paramenter 是参?/p>
Q?Q?message 参数Q?它能够在~译信息输出H口中输出相应的信息Q?br>q对于源代码信息的控制是非常重要的,使用Ҏ是:
#pragma message("消息文本")
当编译器遇到q条指o的时候就在编译信息输出窗口输出相应的信息,把消息文本打印出?
当我们在E序中定义了许多宏来控制源代码版本的时?我们自己有可能都会忘记有没有正确讄q些?
此时我们可以用这条指令在~译的时候就q行?假设我们希望判断自己有没有在源代码的什么地方定义了 _X86q个
宏可以用下面的Ҏ:
#ifdef _X86
#pragma message("_X86 macro activited")
#endif
如果我们定义了_X86q个?应用E序在编译是׃在编译输出框昄:"_X86 macro activited",我们
׃会因׃记得是否定义而苦g.
(2) 另外一个用得比较多的pragma 参数是code_seg 格式?
#pragma code_seg ([[{push|pop},][identifier,]]["section-name"["sectin class"]])
它能够设|程序中函数代码存放的代码段(位置).(另注:该参数可以用来指定在*.obj 文g中存攄?
观察 *.obj可以使用VC自带的dumpbin命o行程?函数?.obj文g中默认的存放字节?.text?
如果code_seg 没有带参数的?则函数存攑֜ .text?br>push [可选参数] 一个记录放到内部编译器的堆栈中,可选参?identifier可以是一个标识符或者节?
pop [可选参数] 一个记录从堆栈的顶端弹?可选参?identifier 可以Z个标识符或者节?
可选参?identifier,当用PUSH指o时?为压入堆栈的记录指派一个标识符,当该标识W被删除的时候和
其相关的堆栈中的记录被弹出堆栈.
"segment-name" [可选参数] 表示函数存放的节?
例如:
默认情况?函数被存攑֜.text?
void func1(){ //stored in .text
}
函数存攑ֈ?.my data?br>#pragma code_seg(".my data1")
void func2()[ stored in my data
}
//r1为标志符,函数放?my data2节中
#pragma code_seg (push,r1,".my data2")
void func3(){ //stored in my data2
}
(3) #pragma once q是一个比较常用的指o,只要在头文g的最开始加入这条指令就能够保证头文件被~译一?
q条指o在VC6里面有,要考虑到兼Ҏ?
(4) #pragma hdrstop 表示预编译到ơؓ?对后面的头文件不在进行预~译.
BCB可以预编译头文g加快链接的速度,但是如果所有头文g都进行预~译可能占有太多盘I间,所以?br>q个选项排除一些头文g.
有时候单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A~译. 可以?pragma startup 指定~译优先U?
如果使用?pragma package(smart_init),BCB׃Ҏ优先U的大小先后~译.
(5) #pragma warning 指o
该指令允许有选择性的修改~译器的警告信息行ؓ.
指o格式:
#pragma warning(warning)specifier;warning-number-list[;warning-specifier;warning-number-list..]
#pragma warning(push[n])
#pragma warning(pop)
主要用到的警告表C有如下几个:
once:只显CZ?警告/错误{?消息
default:重置~译器的警告行ؓ到默认状?
1,2,3,4:四个警告U别
disable:止指定的警告信?
error:指定的警告信息认ؓ是错?
#pragma warning(disable:4507 34;once: 4385;error:164) {h?
#pragma warning(disable:4507 34) //不显C?507 34 可告信?
#pragma warning(once:4385) //4385号信息只昄一?
#pragma warning(error:164) // ?64h息作Z个错?
同时q个pragma warning也支持如下格?br>#pragma warning (push[,n])
#pragma warning (pop)
#pragma warning (push) //保存所有警告消息的现有警告状?br>#pragma warning (push,N) //保存所有警告消息的现有警告状?q且把全局警告{讑֮为n;
#pragma warning (pop) //向栈中弹出最后一个警告消?在入栈和出栈之间做的一切改动取?
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
#pragma warning( pop )
在这D代码的最后,重新保存所有的警告信息(包括4705Q?706?707)
在用标准C++q行~程的时候经怼得到很多的警告信?而这些警告信息都是不必要的提C?
所以我们可以?pragma warning(disable:4786)来禁止该cd的警?br>在vc中用ADO的时候也会得C必要的警告信?q个时候我们可以通过
#pragma warning(disable:4146)来消除该cd的警告信?/p>
(6)#pragma comment(...)
#pragma comment("comment-type"[,commentstring])
该指令将一个注释记录放入一个对象文件或可执行文件中 comment-type cd one of the five
compiler:编译器的版本号和名U放入目标文件中Q本条注释记录将被编译器忽略Q如果你记录cd
提供了commentstring 参数Q编译器生一个警告,
EXQ?#pragma comment (compiler)
exestr:commentstring 参数攑օ目标文g中,在链接的时候这个字W串被攑օ到可执行文g中,当操
作系l加载可执行文gӞ该参数字W串不会被加载到内存中,但是Q该参数字符串可以被dumpbin之类的的
E序查找q打印出来,你可以用q个标志W号版本之cȝ信息潜入到可执行文g中?/p>
lib:q是一个非常常用的关键字,可以帮我们连入一个库文g到目标文件?br>ex:
#pragma comment(lib,"userlib.lib")
linker:
一个链接选项攑օ目标文g中,你可以用这个指令来代替命o行传入的或则在开发环境中讄的链?br>选项Q你可以指定/include 选项来强制包含某个对?br>ex:
#pragma comment(linker,"/include:_mySymbol")
你可以在E序中设|下列链接选项Q?br> /DEFAULTLIB
/EXPORT
/INCLUDE
/MERGE
/SECTION
详情请参考msdn
user: 一般的注释信息攑օ目标文g中,commentstring 参数包含注释的文本信息,q个注释记录被
链接器忽略?br>ex:
#pragma comment(user,"compiled on " _DATE" at "_TIMER_")
使用#pragma 导出 DLL 函数
传统的导出DLL函数的方法是使用模块定义文g(.def),Visual C++ 提供了更z方便的Ҏ,那就
?_declspec()" 关键字后面跟"dllexport",告诉链接d个函?
例如 :
_declspec(dllexport) int _stdcall MyExportFunction(int iTest);
?__declspec(dllexport)"攑֜最前面声明,q接生成的DLL ׃导出函数"_MyExportFunction@4".
上面导出的函数名UC怸是我们希望的,我们希望导出原版"?MyExportFunction". 可以指定用VC
提供?#pragma"指o来指定链接选项.
ex:
#pragma comment(linker,"/EXPORT:MyExportFunction=_MyExportFunction@4")
原Ş: /EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
@ordinal 指定序;NONAME 指定只将函数导出为序?DATA关键字指定导出项为数据项.