??xml version="1.0" encoding="utf-8" standalone="yes"?>
解决办法Q在传送线EPostMessage消息前对栈区上的数据new一份放到堆ZQ堆区的数据是程序员手动?br />建和手动回收的,然后把这些数据传送到另一U程Q由另一U程L动释放delete?br />
问题的生:(x)׃工作U程处理的繁忙,有一些数据在UIU程退出时q没q回Q当UIU程退出后Q数据返?br />由工作线EPostMessage到UIU程QUIU程已经接收不到消息Q故未能手动释放工作U程传过来的堆区内存Q?br />造成内存泄漏?br />
后来Q查到如下网站:(x)
http://stackoverflow.com/questions/3807945/mfc-data-forwarding-to-main-thread-via-postmessage
发现PostMessage是有q回值的Q发送失败返回false?br />
故上面的问题有了(jin)解决Ҏ(gu)Q?br />UIU程Q接收线E)(j)退出后工作U程Q发送线E)(j)PostMessage是返回false的,故可以利用这个返回值来军_由哪个线E来释放q段
PostMessage中传递的内存Q如果传送失败,则由当前PostMessage的线E负责手动回Ӟ如果发送成功就?br />接收U程来负责手动回收?/p>
3.在窗口类中重载PreTranslateMessageq调用将句柄存储在m_hAccelTable中的::TranslateAccelerator.?:TranslateAcceleratorq回?br>的g为PreTranslateMessage的返回?
//virtual BOOL PreTranslateMessage(MSG *pMsg);函数原型
(函数LoadBitmap用于加蝲位图到CBitmapcȝ对象)在视囄的成员函数OnDraw()中添加以下代?
前三行得到指向菜单的指针,W四行调用函数SetMenuItemBitmaps往菜单中增加图?具体参数的含义可参见有关介绍MFC?qing)其成员函数的书卛_.
是犯了(jin)q个错误,我网上走?jin)很?
然后我发现另一文章可以实现同L(fng)效果,不记得网地址?自己写出?
在应用程序的框架cCMainFramedCBitmapcȝ对象,不妨取名为bm_open1和bm_open2,
同样在构造函Cd如下代码:
然后在CMainFrame::OnCreate()中添加如下代?(注意,q里和上面不同了(jin),不用获得父类的指针了(jin))
最后实现的效果一?主要困扰我的问题是图片大没调整好显CZ出来.特作此笔?
上网查了(jin)资料都是在PreTranslateMessageҎ(gu)息进行判?虽然最好的Ҏ(gu)是在q里实现,但我比较喜欢试,惛_q里实现.
|上都说在PreTranslateMessage实现,我就在我的工E中ȝ看PreTranslateMessage函数,当我查了(jin)MSDN后终于明白了(jin),我的消息
全由默认的函数处理了(jin),到OnkeyDown函数中就处理不了(jin)?我把PreTranslateMessage函数Ҏ(gu)下面的样子就可以?
q里q有一个问?关于GetKeyState?查MSDN后知道它的返回值有三种状态的,有按下和弹v以及(qing)cM于大写转键的触发?
但在q里我们不用到触发?按下q回负?弹vq回正?如果上面我们没有对GetKeyState的返回值判断正?
当你W一ơ按左键?也会(x)弹出一个对话框,原因是GetKeyStateq回非零?
若你W一ơ按Ctrl+left时也?x)弹出对话?但第二次不用按Ctrl只按左键也会(x)弹出对话?因ؓ(f)你那时已l触发了(jin)Ctrl?再按一?br>Ctrl+left;下次按left׃?x)弹出对话框?那时Ctrl失效?(q里是失效还是弹起分不清?调试看它的返回?应该是弹?因ؓ(f)
按下Ctrl的值时它的值都?127?128两值变?x高(sh)(the high-order bit)?,最低位(the low-order bit)恒ؓ(f)1)
但感觉上q是失效,不然也不用第二次来恢复Ctrl的?!!!!!!
所以上面的GetKeyState必须判断q回值的正负!
/Files/dragon/Addrctext.rar
最主要是在修改的代码在q里:
最后我?x)用LoadCursor加蝲自己ȝ鼠标图标?
首先,"插入"->"资源"->"Cursor"->"新徏"
?x)有一个编辑图标的H口,然后你随便画个图?/p>
然后按保存文g,注意,q里要把保存的文件保存到你的工程文g夹下,?.dsw文g所在的位置.
保存?你的工程文g夹下?x)多Z个文?一个是*.rc,一个是resourch.h
W三?在FileView里右击Resource Files选择"d文g到目?,然后打开你的资源文g*.rc;
此时你会(x)多出一个资源视?q时不要双击*.rc不然它会(x)在右~辑框打开?应该点击下方的资源视?
再查看视N文g夹下的文?点击所??,最后在左编辑框?x)显CZ的资源了(jin)!双击你自己定义的?br>标右~辑框会(x)出现它的~辑H口,q里回到文g视图,你会(x)发现Resource Files多了(jin)一?.cur文g
再把增加的resource.h文gd到Header Files?
q时你查看resource.h文g,其实它已l帮你定义了(jin)你的鼠标ID,你自己手动在工程文g夹下用文本编?br>器查?.rc文g,其实它已l帮你做?jin)好多工?
最后再把resource.h文g包含?.cpp文g下修改上面的代码卛_!
最后代?里面有另一文?我看?jin)那自己再ȝq篇?:
/Files/dragon/Addretext1.rar
dc.SetViewportOrg(rect.Width(),0);//把原点移臌口的右上?br> dc.Rectangle(0,0,-200,200);
dc.SetViewportOrg(0,0);//Ud原来的位|?br> dc.Rectangle(0,0,200,200);
}
׃SetViewportOrg的参数是讑֤坐标,与逻辑坐标无关,所以当它移动坐标u时与上一ơ的坐标轴的位置?br>关的,q且GetClientDC获得的是讑֤坐标,更加可以怿它每一ơ设|的坐标的正?它的主要作用?原?br>(左上?U至参数指定的点.
至于SetWindowOrg是采用逻辑坐标q行讄坐标原点?它可以在对应的逻辑映射模式下进行设|原?除了(jin)
默认的坐标系是原点在左上?向ؓ(f)?向右为正?其它非自定义模式都是原点在左上角,向下,向右为正?
和我们数学的二维坐标pM?Z(jin)更好的体现出SetWindowOrg我将H口分别变成我们数学上四个像?它的
作用是这L(fng):有一点point1,先将它从讑֤坐标变成该映模式下的逻辑坐标(注意:一般设备坐标点?,+ 逻辑
坐标转换后是+,-?由映模式决?,然后它移动它的奇对称点得坐标系跟着Ud,当它的奇对称点到辑֎?br>?原来的原点就到达point1的位|?(SetWindowOrg的参数就是point1的奇对称?
CRect rect;
GetClientRect(&rect);
没设|前已经是第四象限了(jin)!
W一象限:
CClientDC dc(this);
dc.SetMapMode(MM_LOENGLISH);
CPoint point1(0,rect.Height());//把原点移到左下角
dc.DPtoLP(&point1);//先将讑֤坐标变成逻辑坐标!SetWindowOrg要求?
dc.SetWindowOrg(-point1.x,-point1.y);//两个负号取奇对称?UdU点使得整个坐标跟着UM对称点移到原?br> CRect rect1(0,0,200,200);
dc.Rectangle(&rect1);
W二象限:
CClientDC dc(this);
dc.SetMapMode(MM_LOENGLISH);
CPoint point1(rect.Width(),rect.Height());//把原点移到右下角
dc.DPtoLP(&point1);//逻辑坐标是相对于MM_LOENGLISHq行转换?得到的坐标肯定是(+,-)
dc.SetWindowOrg(-point1.x,-point1.y);
dc.Rectangle(0,0,-200,200);
W三象限:
CClientDC dc(this);
dc.SetMapMode(MM_LOENGLISH);
CPoint point1(rect.Width(),0);//把原点移到右上角
dc.DPtoLP(&point1);
dc.SetWindowOrg(-point1.x,-point1.y);
dc.Rectangle(0,0,-200,-200);
上面的SetWindowOrg分开ȝ,我要的效果是要像上面的SetViewportOrgq样q着?
其实在移完一个原点后,把原点移?0,0)再移q就可以做到?(W四象限忽略)
CRect rect;
GetClientRect(&rect);
int width=rect.Width();
int height=rect.Height();
CClientDC dc(this);
dc.SetMapMode(MM_LOENGLISH);
CPoint point1(0,height);
dc.DPtoLP(&point1);
dc.SetWindowOrg(-point1.x,-point1.y);
CRect rect1(0,0,200,200);
dc.Rectangle(&rect1);
dc.SetWindowOrg(0,0);
point1=CPoint(width,height);
dc.DPtoLP(&point1);
dc.SetWindowOrg(-point1.x,-point1.y);
dc.Rectangle(0,0,-200,200);
dc.SetWindowOrg(0,0);
point1=CPoint(width,0);
dc.DPtoLP(&point1);
dc.SetWindowOrg(-point1.x,-point1.y);
dc.Rectangle(0,0,-200,-200);
如果我中间没有用dc.SetWindowOrg(0,0);p思考了(jin)!
CClientDC dc(this);
dc.SetMapMode(MM_LOENGLISH);
CPoint point1(0,height);
dc.DPtoLP(&point1);
dc.SetWindowOrg(-point1.x,-point1.y);
CRect rect1(0,0,200,200);
dc.Rectangle(&rect1);
//先明上一步我们的坐标原点在左下角,要把原点Ud右下?此时右下角相对当时的坐标pL(width,0)
point1=CPoint(width,0);//U至(width,0)
dc.DPtoLP(&point1);//变换成ؓ(f)逻辑坐标,但符号变?sh)?+,-),因ؓ(f)在MM_LOENGLISH映射模式?br> dc.SetWindowOrg(-point1.x,point1.y);//(width,0)?+,0)则它的对U点应ؓ(f)(-,0)才对,
//只要point1前一个变号即?W二个ؓ(f)0不用?
dc.Rectangle(0,0,-200,200);
//先明上一步我们的坐标原点在右下角,要把原点Ud右上?此时右上角相对当时的坐标pL(0,height)
point1=CPoint(0,height);//U至(0,height)
dc.DPtoLP(&point1);//变换成ؓ(f)逻辑坐标,但符号变?sh)?+,-),因ؓ(f)在MM_LOENGLISH映射模式?br> dc.SetWindowOrg(point1.x,point1.y);//(0,height)?0,+)则它的对U点应ؓ(f)(0,-)才对,和逻辑坐标同号,不用?
dc.Rectangle(0,0,-200,-200);
可以看出SetWindowOrg每一ơ执行都改变?sh)ơ坐标系的位|?!
q个Ҏ(gu)改变子窗?(叛_)弹出H口,H口的大?位置和Z序!
从我的看法来觉得,Z序是相Ҏ(gu)C器q面的垂直方向窗口显C的序!
参数:
pWndInsertAfter
在z序中的位于被|位的窗口前一个窗口句柄。该参数必须Z个CWnd指针Q或下列值的地址(因ؓ(f)参数是指?之一Q?br>wndBottom 窗口置于Z序的底部;如果CWnd是一个顶层窗?q个H口失去顶U位|?它将攑֜所有窗口的底部!
wndTop 窗口置于Z序的剙
wndTopMost 窗口置于所有非层H口之上。即使窗口未被激zȝ口也保持顶U位|?br>wndNoTopMost 窗口置于所有非层H口之上Q即在所有顶层窗口之后)(j)。如果窗口已l是非顶层窗口则该标志不起作用?br>wndTop是要将它放到Z序的首位置;
x: 以客户坐标指定窗口新位置的左边界.
Y: 以客户坐标指定窗口新位置的顶边界.
cx:以像素指定窗口的新的宽度.
cy:以像素指定窗口的新的高度.
uFlags:H口寸和定位的标志。该参数可以是下列值的l合Q?br> SWP_ASNCWINDOWPOSQ如果调用进E不拥有H口Q系l会(x)向拥有窗口的U程发出需求。这防止调用线E在其他U程处理需求的时候发生死锁?br> SWP_DEFERERASEQ防止生WM_SYNCPAINT消息?br> SWP_DRAWFRAMEQ在H口周围M个边框(定义在窗口类描述中)(j)?br> SWP_FRAMECHANGEDQ给H口发送WM_NCCALCSIZE消息Q即使窗口尺寸没有改变(sh)?x)发送该消息。如果未指定q个标志Q只有在改变?sh)(jin)窗口尺寸时才发送WM_NCCALCSIZE?br> SWP_HIDEWINDOW;隐藏H口?br> SWP_NOACTIVATEQ不Ȁzȝ口。如果未讄标志Q则H口被激z,q被讄到其他最高H口或非最高l的剙Q根据参数hWndlnsertAfter讄Q?br> SWP_NOCOPYBITSQ清除客户区的所有内宏V如果未讄该标志,客户区的有效内容被保存ƈ且在H口寸更新和重定位后拷贝回客户区?br> SWP_NOMOVEQ维持当前位|(忽略X和Y参数Q?br> SWP_NOOWNERZORDERQ不改变z序中的所有者窗口的位置?br> SWP_NOREDRAW:不重L变的内容。如果设|了(jin)q个标志Q则不发生Q何重d作。适用于客户区和非客户区(包括标题栏和滚动条)(j)和Q何由于窗回移动而露出的父窗口的所有部分。如果设|了(jin)q个标志Q应用程序必L地使窗口无效ƈ区重ȝ口的M部分和父H口需要重ȝ部分?br> SWP_NOREPOSITIONQ与SWP_NOOWNERZORDER标志相同?br> SWP_NOSENDCHANGINGQ防止窗口接收WM_WINDOWPOSCHANGING消息?br> SWP_NOSIZEQ维持当前尺寸(忽略cx和cy参数Q?br> SWP_NOZORDERQ维持当前Z序(忽略pWndInsertAfter参数Q?br> SWP_SHOWWINDOWQ显C窗口?br> q回|(x)如果函数成功Q返回gؓ(f)非零Q如果函数失败,q回gؓ(f)零。若惌得更多错误消息,误用GetLastError函数?br> 备注Q如果设|了(jin)SWP_SHOWWINDOW和SWP_HIDEWINDOW标志Q则H口不能被移动和改变大小。如果用SetWindowLoog改变?sh)(jin)窗口的某些数据Q则必须调用函数SetWindowPos来作真正的改变。用下列的l合标志QSWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED?br> 有两U方法将H口设ؓ(f)最层H口Q一U是参数pWndInsertAfter讄为wndTopMostq确保没有设|SWP_NOZORDER标志Q另一U是讄H口在Z序中的位|以使其在其他存在的H口之上。当一个窗口被|ؓ(f)最层H口Ӟ属于它的所有窗口均为最层H口Q而它的所有者的z序ƈ不改变?br> 如果wndTopMost和wndNoTopMost标志均未指定Q即应用E序要求H口在激zȝ同时改变其在Z序中的位|时Q在参数hWndinsertAfter中指定的值只有在下列条g中才使用Q?br> 在hWndlnsertAfter参数中没有设定wndNoTopMost和wndTopMost标志?br> 由hWnd参数标识的窗口不是激zȝ口?br> 如果未将一个非Ȁzȝ口设定到z序的端Q应用程序不能激z该H口。应用程序可以无M限制地改变被Ȁzȝ口在Z序中的位|,或激zM个窗口ƈ其Ud最高H口的顶部或非最高H口的顶部?br> 如果一个顶层窗口被重定位到z序的底部QwndBottomQ或在Q何非最高序的窗口之后,该窗口就不再是最层H口。当一个最层H口被置为非最Q则它的所有者窗口和所属者窗口均为非最层H口?br> 一个非最端H口可以拥有一个最端H口Q但反之则不可以。Q何属于顶层窗口的H口Q例如一个对话框Q本w就被置为顶层窗口,以确保所有被属窗口都在它们的所有者之上?br> 如果应用E序不在前台Q但应该位于前台Q就应调用SetForegroundWindow函数来设|?/p>
我手动创Z(jin)几个控g,然后调用下面的函数进行设|tab序!未设|之前是按控件的创徏序为tab序:
void CTest4Dlg::OnSetOrder()
{
CWnd * pNum1=GetDlgItem(IDC_NUM1);
CWnd * pNum2=GetDlgItem(IDC_NUM2);
CWnd * pResult=GetDlgItem(IDC_RESULT);
CWnd * pEqual=GetDlgItem(IDC_EQUAL);
CWnd * pClear=GetDlgItem(IDC_CLEAR);
CWnd * pSetOrder=GetDlgItem(IDC_SETORDER);
EquBtn.SetWindowPos(&wndTop,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);//wndTop是设|ؓ(f)Z序的最剙!
Num2.SetWindowPos(pEqual,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
SetOrder.SetWindowPos(pNum2,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
Result.SetWindowPos(pSetOrder,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
Clear.SetWindowPos(pResult,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
}
开始时它的tab序是这L(fng),如下?
当按?jin)设|按?OnSetOrder)?如下?
W二U方法好一?但实现v来也比较难一?
1.新徏一个基于对话框的工Etest3;我把"定"?取消"都删除了(jin)!
2.在对话框中插入如囄控g(其中Button1的ID是IDOK)
3.叛_工程d一个MFCc?cd为CMyEdit
4.然后叛_q个新类dWM_KEYDOWN消息函数OnKeyDown;q加如下代码:
void CMyEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if(nChar==VK_RETURN)
{
CTest3Dlg * pwnd=(CTest3Dlg *)GetParent();//Z是主对话框类,所以在CPP文g中加#include "test3Dlg.h"
//不要在头文g中加,在头文g中会(x)出错?
pwnd->NextDlgCtrl();
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
5.然后主对话框中的两个编辑框定义兌变量:
在classwizard中选择 member variables 选项Qclass name选择对话框类Qcontrol ids中选择~辑框的idP然后选择add variable按扭。在对话框中 categary选择controlQ?variable type 刚才定义的类m_myedit1,m_myedit2;那时它会(x)提示你加头文?br>"MyEdit.h" 你此时就在头文gTest3Dlg.h?include "MyEdit.h"
6.Z(jin)让焦点落在按??若按下回车响应按?的函?我加?jin)两个函?
void CTest3Dlg::OnOK()//其中q个是按钮1的响应函?br>{
// TODO: Add extra validation here
MessageBox("dragon");
//CDialog::OnOK();//我ؓ(f)?jin)不让默认的OnOK函数执行,它屏蔽?
}
void CTest3Dlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)//叛_cL加的!
{
// TODO: Add your message handler code here and/or call default
if(nChar==VK_RETURN)
OnOK();
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}
1.通过Create函数手动创徏一个IP控g.
开始时我在OnInitDialog()函数中这样写?
CIPAddressCtrl IPAddress;
UINT nID=101;
IPAddress.Create(WS_CHILD |WS_VISIBLE ,CRect(20,20,300,43),this,nID);
但运行之后看不到有IP控g出来,后来才发现原来我的IPAddress是一个局部变?当OnInitDialog()函数q回?q个变量撤销?
所以不?x)有控g出来!!
只要把CIPAddressCtrl IPAddress;攑ֈ头文件中定义为成员变量就O(jin)K?
如果上面的Create函数的第一个参数没有|WS_VISIBLE;我们可以Create函数后加q一?IPAddress.ShowWindow(SW_SHOW);
感觉上Create函数在每一个控仉都有,创徏的方法也是大同小异了(jin)?
2.下面的是我在Z一个对话框的工E中d一个IP控g中所写的:
先获得控件的指针:
CIPAddressCtrl * pIP=(CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS);
void ClearAddress( );
q个函数IP控g里的内容清空.
BOOL IsBlank( ) const;
q个函数是当IP控g里一个数字都没有才返回真?全ؓ(f)0都返回假,0也是数字!调用ClearAddress( )后刚好可以IsBlank()反回?
试代码如下:
pIP->ClearAddress();
if(pIP->IsBlank())
{
MessageBox("IP全ؓ(f)I?);
}
int GetAddress(BYTE& nField0, BYTE& nField1, BYTE& nField2, BYTE& nField3);
int GetAddress(DWORD& dwAddress);
当控件内容ؓ(f)I时,x有数?q?也没?q回0,0,0,0.和控件全?的情况一?
获得IP地址:(两种Ҏ(gu),选其一)
BYTE nf1,nf2,nf3,nf4;
pIP->GetAddress(nf1,nf2,nf3,nf4);
CString str;
str.Format("%d.%d.%d.%d",nf1,nf2,nf3,nf4);//q里的nf得到的值是IPg(jin).
MessageBox(str);
/*
DWORD dw;
pIP->GetAddress(dw);
CString str;
WORD hiWord=HIWORD(dw);
WORD loWord=LOWORD(dw);
BYTE nf1=HIBYTE(hiWord);
BYTE nf2=LOBYTE(hiWord);
BYTE nf3=HIBYTE(loWord);
BYTE nf4=LOBYTE(loWord);
str.Format("%d.%d.%d.%d",nf1,nf2,nf3,nf4);
MessageBox(str);
*/
void SetAddress(BYTE nField0, BYTE nField1, BYTE nField2, BYTE nField3);
void SetAddress(DWORD dwAddress);
讄IP地址:(两种Ҏ(gu),选其一)
pIP->SetAddress(127,0,0,1);
pIP->SetAddress((DWORD)0x7F000001);//q两行的效果都是一L(fng)!
void SetFieldRange(int nField, BYTE nLower, BYTE nUpper);
讄每一个域的范?(nField??的?nLower和nUpper的范围都??55.可以出范围,但控件也q是默认讄??55?
pIP->SetFieldRange(0,5,127);//讄每一个域的范?W一个参数是域的下标,W二和第三个是范?
pIP->SetFieldRange(1,5,127);//当输入比5时,?,当失去输入焦Ҏ(gu),它会(x)重置?.
pIP->SetFieldRange(2,5,127);//当输入比127大时,?28,它会(x)自动变回127
pIP->SetFieldRange(3,5,127);
void SetFieldFocus(WORD nField);
nField的gؓ(f)0?;表示域的下标!该函数是使输入焦点落在四个域的指定域?
q个函数要在消息响应时才能体现出?
试代码:
void CTestDlg::OnButton2()
{
// TODO: Add your control notification handler code here
CIPAddressCtrl * pIP=(CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS);
pIP->SetFieldFocus(2);
}
说明:GetLogicalDriveStrings函数一个缓冲区lpBuffer填入在计机上存在的盘盘符.
参数说明:
nBufferLength是缓冲区lpBuffer的大?以字节ؓ(f)单位.它的大小不包含最后的I字W?如果它的gؓ(f)?~冲Z可用.
lpBuffer指向一个接收各U以零结字符串缓冲区,一个空字符用来区分各个可用盘?最后在末尾有再以空字符l尾,假如
你的?sh)脑上有C,D两个盘盘符,则它能得C个字W串?
'C',':','\',' ','D',':','\',' ',' '
?C:\<null>D:\<null><null>
q回?
如果函数成功l束,q回值是获得的字W串长度,以字节ؓ(f)单位,不包括最后的一个空字符,好像上面的字W串获得的长度就?;盘
盘符的个数自乘(sh)4是?C:一个ANSI-ASCII码的I字W是一个字?而一个Unicode码的I字W是两个字节.如果q个~冲Z
够大,q回g(x)比nBufferLength?q是~冲求去获得全部盘盘符的原?
如果函数p|,q个q回值是0;用GetLastError可以捕获q个错误信息!
W一U? (如果是基于对话框的工E?我们先添加菜单和加速键资源,然后叛_d话框属性添加菜?
首先在资源文件Accelerator中添加快捷键资源 ID选择你要兌菜单的名称 然后再设|你的快捷键.什?下一??h文g中加入一?nbsp; HACCEL hAccel;变量 然后在OnInitDialog或初始化中加入hAccel=::LoadAccelerators(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_ACCELERATOR1)); 后面的参数是加速键资源文g?
最后在PreTranslateMessage(MSG* pMsg) 中加?
if(::TranslateAccelerator(GetSafeHwnd(),hAccel,pMsg))
return true;
q样 以后只要在Accelerator资源文g中添加快捷键可以了(jin)
注意Q??/span>加快捷键的ID一定要与菜单ID一?/span> q样才能响应.现在只需要在此菜单项中加入OnCommand消息的处理就可以?
W二U? q是在资源文件Accelerator中添加快捷键资源 ID自己定义一?然后再设|你的快捷键.下一?..是?h文g中定义一个快捷键对象
HACCEL m_hAccel;
然后?cpp文g中初?br> m_hAccel = ::LoadAccelerators(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_ACCELERATOR1));
IDR_ACCELERATOR1Z的加速资源名U?注意不是刚刚定义的加速键ID.
再添加PreTranslateMessage消息处理 在里面加入以下代?
//保存快捷键被启用
if(m_hAccel != NULL)
{
if (TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
return TRUE;
}
再添加OnCommand消息处理 加入以下代码:
//响应加速键
switch(LOWORD(wParam))
{
case SHOW_DIAL0G: //加速键ID
//...d处理语句
break;
case SHOW_DIALOG_02: //加速键ID
//...d处理语句
break;
}
自己加的:在我看的代码?它是利用对话框加菜单?当加?jin)菜单?把菜单挂到对话框,然后响应一个菜单项.再在对话框类中加虚函数PreTranslateMessage,在些数里的代码如?
if( pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_F2)
this->PostMessage(WM_COMMAND,IDM_SHOW);//IDM_SHOW是响应的菜单ID
}
return CDialog::PreTranslateMessage(pMsg);
q样我就可以响应F2的加速键?!
转蝲:http://www.cnblogs.com/thankgoodness/articles/1136617.html
新徏一个基于对话框的工E?
(1)我加载的工具栏有十个64*42的按?所以对话要事先拉得比工h?
(2)插入一个工h,初始ID为IDR_TOOLBAR1;然后在上面加十个64*42的按?我加载的位图?nbsp; 640*42?q个可以出来吧!
(3)在C**DlgcL加一个CToolBar变量m_ToolBar;再在q个cL加OnInitDialog()函数,在这函数里添加如下代码加载工h到对话框!
if (!m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_ToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
m_ToolBar.ShowWindow(SW_SHOW);
然后~译q行!
(4)叛_你的工具栏点属?看到文g名的内容?res\toolbar1.bmp;q下你也自然惛_工程下的res文g夹了(jin)?你要加入的囄改名为toolbar1.bmp复制到res文g下去覆盖原来的toolbar1.bmp;q时VC?x)弹Z个对话框?........\toolbar1.bmpq个文g已在Microsoft Developer Studio之外补修?你要重新载入它吗?"
你按"?p?
q时你编辑的工具栏相应会(x)有变化的?
(5)~译q行后是q(sh)行的,那时我把我工h的左数第一个按钮改?jin)ID再编译运行就O(jin)K?/span>!
q个序不能倒啊,呵呵!因ؓ(f)toolbar1.bmp原先不存在的,~译q行时它?x)自q成的,但我们生成后再去覆盖׃一样了(jin)!
以下是我做成功的界面和用到的toolbar1.bmp?因ؓ(f)不能上传bmp格式,我把后缀Ҏ(gu)jpg才上传了(jin))
紧作W记之用,如果觉得q个单勿嘲笑!
如:(x)
// 打开HKEY_LOCAL_MACHINE主键下的SoftWare\\Cleaner\\Cleaner子键
HKEY hKEY;
HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
long ret0=(::RegOpenKeyEx(hKeyRoot,"SoftWare\\Cleaner\\Cleaner",0,KEY_READ,&hKEY));
if(ret0!=ERROR_SUCCESS)//如果无法打开hKEY,则中止程序的执行
{
AfxMessageBox("错误Q无法打开有关的hKEY");
return;
}
2. d注册?br> LONG RegQueryValueEx(
HKEY hKey, // handle to key打开注册表指?br> LPCTSTR lpValueName, // value name要读取的键名U?br> LPDWORD lpReserved, // reserved must be NULL. 必须是NULL
LPDWORD lpType, // type bufferQ键cd。我最常用REG_SZ,REG_DWORD
LPBYTE lpData, // data buffer。保存查询结果的~冲?br> LPDWORD lpcbData // size of data buffer。缓冲区大小
);
如:(x)
// hKEY是上面打开时得到的指针?br> LPBYTE getValue = new BYTE[80];//得到的键?br> DWORD keyType = REG_SZ;//定义数据cd
DWORD DataLen = 80;//定义数据长度
CString strUser = _T("Version");//要查询的键名U?br> long ret1=::RegQueryValueEx(hKEY,strUser,NULL,&keyType,getValue,&DataLen);
if(ret1!=ERROR_SUCCESS)
{
AfxMessageBox("错误Q无法查询有关的注册表信?);
return;
}
3. 写注册表
LONG RegSetValueEx(
HKEY hKey, // handle to key。打开注册表的指针
LPCTSTR lpValueName, // value name 要写入的?br> DWORD Reserved, // reserved 必须?
DWORD dwType, // value type 写入值类?br> CONST BYTE *lpData, // value data 要写入的数据
DWORD cbData // size of value data 。数据SIZE
);
如:(x)
// 写注册表。修改Version?.0.12
// 写入CStringcd的数?br>CString strVersion = _T("Version");//要写入的键名U?br>LPCTSTR strVersionValue = "1.0.12";
long ret = ::RegSetValueEx(hKEY, strVersion, 0, REG_SZ, (const BYTE *) strVersionValue, strlen(strVersionValue)+1);
if(ret!=ERROR_SUCCESS)
{
AfxMessageBox("错误Q无法查询有关的注册表信?);
return;
}
[/code]
4. 创徏一个新?br>LONG RegCreateKeyEx(
HKEY hKey, // handle to open key。打开的注册表指针
LPCTSTR lpSubKey, // subkey name。子键名U?br> DWORD Reserved, // reserved。必Mؓ(f)0
LPTSTR lpClass, // class string。已l存在时用,一般ؓ(f)NULL
DWORD dwOptions, // special options
//默认值REG_OPTION_VOLATILEQ保存在注册表,下次开Z然存?br> //REG_OPTION_VOLATILEQ保存在内存
//REG_OPTION_BACKUP_RESTORE
REGSAM samDesired, // desired security access。操作权限。一般KEY_ALL_ACCESSQ除非有Ҏ(gu)需要,h阅MSDN
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // inheritance。承性。一般ؓ(f)NULL
PHKEY phkResult, // key handle 。返回该键值镇?br> LPDWORD lpdwDisposition // disposition value buffer
//REG_CREATED_NEW_KEY The key did not exist and was created.
//REG_OPENED_EXISTING_KEY The key existed and was simply opened without being changed.
);
5. 删除一个键
LONG RegDeleteKey(
HKEY hKey, // handle to open key
LPCTSTR lpSubKey // subkey name
);
6. 删除一个键?br>LONG RegDeleteValue(
HKEY hKey, // handle to key
LPCTSTR lpValueName // value name。值名Uͼ不是打开的那个指针,是查询到的指针,如果为空RegSetValueEx创徏的值将被删?br>);
7. h注册?br>LONG RegFlushKey(
HKEY hKey // handle to key to write。写入所有的|在给定的指针
);
//q个函数是将改变数据直接写到盘?sh),不要频繁使用Q会(x)影响性能
8. 导入一个注册表文g到指定的键下
LONG RegLoadKey(
HKEY hKey, // handle to open key
LPCTSTR lpSubKey, // subkey name
LPCTSTR lpFile // registry file name
);
//没有?/p>
9. 关闭打开的注册表
LONG RegCloseKey(
HKEY hKey // handle to key to close
);
基本思\如下:
(1)int(用户C盘序列号^用户名^1234567890123)生成一个序列号N(是字W串CStringcd);
(2)pȝ(g)到你的软gq没注册p动生成一个文?文g保存?sh)(jin)你输入的用户名和序列?nbsp; N.公司?x)叫你EMailq个文gC们公叔R?公司再返回一个注册码?
(3)如果发回一个注册码,pȝ?x)判?用户名^用户C盘序列号 =注册?/span>?来进入系l的!注册?nbsp; 功后再把用户名和注册码保存到pȝ文g(ini)中下ơ登陆就?x)检这个文?q次是判?nbsp; 用户名^注册?用户C盘序列号? 来判断进入系l了(jin)!
推理:
从上得到三条有用信息:
(1)用户名对于用户和公司来说都是已知?br>(2)int(用户C盘序列号^1234567890123)=N(l过Format变成字符?
(3)用户名^用户C盘序列号=注册?/span>
?1)和上面的异或性质推出: atoi(N)^1234567890123=用户C盘序列号 (3)
?2)和异或性质推出: 注册?用户C盘序列号^用户?/span> (4)
?3),(4)式再推出
注册?atoi(N)^1234567890123^用户?/span>
用户名和序列号N都发l了(jin)公司,公司是利用q条公司q行求注册码!
理解?jin)这个思\后我写?jin)个生成注册码的E序:
是逆运吧?假如我是那公?发到我手上的信息已经有两个了(jin),用户名和序列号N;q样,主要我用atoi(序列?^1234567890123可以求得注册码?只不q在做的时候就是类型{换有点复杂吧?!
Z(jin)便于复习(fn)把代码脓(chung)出来:
LPCTSTR lpRootPathName="C:\\";
LPTSTR lpVolumeNameBuffer=new char[12];
DWORD nVolumnNameSize=12;
DWORD MaximumComponentLength;
DWORD FileSystemFlags;
LPTSTR lpFileSystemNameBuffer=new char[10];
DWORD FileSystemNameLength=12;
GetVolumeInformation(lpRootPathName,lpVolumeNameBuffer,nVolumnNameSize,&m_VolumnSerialNumber,&MaximumComponentLength,&FileSystemFlags,lpFileSystemNameBuffer,FileSystemNameLength);
delete(lpVolumeNameBuffer);
delete(lpFileSystemNameBuffer);
上面是C盘序列号攑ֈDWORDcd的m_VolumnSerialNumber?
sSerialNumber.Format("%d",m_VolumnSerialNumber^1234567890123);
生成的序列号׃存在sSerialNumber?
int(用户C盘序列号^1234567890123)=N已经完成!
下面?用户名^用户C盘序列号=注册?br>CString sName,sNameCode,sCode;
this->m_EdtUserName.GetWindowText(sName);
char * cNameCode=sName.GetBuffer(sName.GetLength());
DWORD dNameCode=*cNameCode;
sCode.Format("%d",m_VolumnSerialNumber^dNameCode);
sCode׃存(sh)(jin)注册?
BOOL WritePrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName ); |
CString strName,strTemp; int nAge; strName="张三"; nAge=12; ::WritePrivateProfileString("StudentInfo","Name",strName,"c:\\stud\\student.ini"); |
strTemp.Format("%d",nAge); ::WritePrivateProfileString("StudentInfo","Age",strTemp,"c:\\stud\\student.ini"); |
DWORD GetPrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName ); |
CString strStudName; int nStudAge; GetPrivateProfileString("StudentInfo","Name","默认姓名",strStudName.GetBuffer(MAX_PATH),MAX_PATH,"c:\\stud\\student.ini"); |
UINT GetPrivateProfileInt( LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName ); |
nStudAge=GetPrivateProfileInt("StudentInfo","Age",10,"c:\\stud\\student.ini"); |
CString strTemp,strTempA; int i; int nCount=6; file://共有6个文件名需要保?br>for(i=0;i {strTemp.Format("%d",i); strTempA=文g? file://文g名可以从数组,列表框等处取? ::WritePrivateProfileString("UseFileName","FileName"+strTemp,strTempA, "c:\\usefile\\usefile.ini"); } strTemp.Format("%d",nCount); ::WritePrivateProfileString("FileCount","Count",strTemp,"c:\\usefile\\usefile.ini"); file://文件L写入,以便d. |
nCount=::GetPrivateProfileInt("FileCount","Count",0,"c:\\usefile\\usefile.ini"); for(i=0;i {strTemp.Format("%d",i); strTemp="FileName"+strTemp; ::GetPrivateProfileString("CurrentIni",strTemp,"default.fil", strTempA.GetBuffer(MAX_PATH),MAX_PATH,"c:\\usefile\\usefile.ini"); file://使用strTempA中的内容. } |
PostMessage消息WM_QUIT发送到消息队列?׃PostMessage的立卌?即结?执行下一句语句结束整个程?消息q挂在消息队列中未处理故出错!!
[一些小?j)得]
?
CFileDialog GetFile(TRUE,NULL,NULL,OFN_FILEMUSTEXIST,"Microsoft Excel(*.xls)|*.xls|All Files(*.*)|*.*||");
CFileDialog GetFile(打开文g对话?TRUE),扩展?NULL),文g?NULL),风格-文g必须存在(OFN_FILEMUSTEXIST),查看文gcd-EXCEL文g,所有文?Microsoft Excel(*.xls)|*.xls|All Files(*.*)|*.*||);
风格的宏定义
#define OFN_READONLY 0x00000001
#define OFN_OVERWRITEPROMPT 0x00000002
#define OFN_HIDEREADONLY 0x00000004
#define OFN_NOCHANGEDIR 0x00000008
#define OFN_SHOWHELP 0x00000010
#define OFN_ENABLEHOOK 0x00000020
#define OFN_ENABLETEMPLATE 0x00000040
#define OFN_ENABLETEMPLATEHANDLE 0x00000080
#define OFN_NOVALIDATE 0x00000100
#define OFN_ALLOWMULTISELECT 0x00000200
#define OFN_EXTENSIONDIFFERENT 0x00000400
#define OFN_PATHMUSTEXIST 0x00000800
#define OFN_FILEMUSTEXIST 0x00001000
#define OFN_CREATEPROMPT 0x00002000
#define OFN_SHAREAWARE 0x00004000
#define OFN_NOREADONLYRETURN 0x00008000
#define OFN_NOTESTFILECREATE 0x00010000
#define OFN_NONETWORKBUTTON 0x00020000
#define OFN_NOLONGNAMES 0x00040000 // force no long names for 4.x modules
#if(WINVER >= 0x0400)
#define OFN_EXPLORER 0x00080000 // new look commdlg
#define OFN_NODEREFERENCELINKS 0x00100000
#define OFN_LONGNAMES 0x00200000 // force long names for 3.x modules
#define OFN_ENABLEINCLUDENOTIFY 0x00400000 // send include message to callback
#define OFN_ENABLESIZING 0x00800000
#endif /* WINVER >= 0x0400 */
#if (_WIN32_WINNT >= 0x0500)
#define OFN_DONTADDTORECENT 0x02000000
#define OFN_FORCESHOWHIDDEN 0x10000000 // Show All files including System and hidden files
#endif // (_WIN32_WINNT >= 0x0500)
q个׃解释?应该都能看懂?/p>
需要注意的?用了(jin)CFileDialog之后,?x)把E序的当前\径设|成选中文g的\?br>所?如果E序里有用到IO讉K或者数据库讉K之类的本地操作时,需要注意你的当前\?br>用相对\径的话就不是原来你的E序路径?切记!
转蝲?http://blog.csdn.net/beiouwolf/archive/2007/04/09/1557219.aspx
(2)然后我们要做的是看看加蝲位图的图片大?拉一个随便大的"囑փ"控g,叛_属??br> "常规"属性页?cd"中选择"位图";然后"囑փ"选择你要加蝲的位图ID(q个位图资源?
先插入到工程?,然后关闭属性对话框,可以在最右下角中昄你的囄大小?
(3)因ؓ(f)q样没办法调整图片覆盖整个对话框,我就把这个图片控件删除掉,再事先把对话框调
整大到刚刚囄的大?调整的方法是Ҏ(gu)边看最右下方的昄,调整到是囄的大ؓ(f)
?好啦,对话框调整后,我拉Z?囄"控g,注意,q次我们要从对话框的最左上角一
直拉到对话框的最右下角才?q才能确保图片整个覆?拉出来后,按照刚刚的做法?nbsp;
位图加蝲q来,看看效果!
来说说先弹出后消q实现,话框创徏一个新c?个类dOnInitDialog()函数
和OnTimer()函数,代码如下:
void CDBegin::OnTimer(UINT nIDEvent)
{
CDialog::OnTimer(nIDEvent);
this->KillTimer(1);
this->OnCancel();
//下面是对话框消失后要做的工作!
}
BOOL CDBegin::OnInitDialog()
{
CDialog::OnInitDialog();
this->SetTimer(1,1400,NULL);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
最后在调用此对话框的类中添加头文g卛_!!(记得要添?
①用l图工具Q我用的是FireworksQ制作三?4位位图?/font>其中Q?/p>
30.bmp为工具可用时昄的位图:(x)
31.bmp为工具不可用Q变灎ͼ(j)时显C的位图Q?/p>
32.bmp为鼠标进入工h钮时昄的位图:(x)
q里Q每张位图中按钮的个数和大小可根据实际应用进行修改,本例中,每张位图?4个按钮,每个按钮大小?0×20?/p>
q个制作q程是比较繁琐的Q首先我把找来的图片{换成24位位图,在Fireworks下把它{换ؓ(f)20×20的大后保存Q再用Fireworks把它转换为灰色位囑֒带边框的位图q分别保存。然后再把三l小囄分别拼接hp?jin)?/p>
②把三个位图导入资源Q作为Bitmap资源Q?/font>Q尽在VC++下不能显C和~辑Q但使用上没有问题。把三个位图的ID依次改ؓ(f)Q?br>IDB_TOOLBARCOLOR、IDB_TOOLBARDISABLE、IDB_TOOLBARHOT
③在资源的工h目中添加一个新的工hQ如图)(j)QID改ؓ(f)IDR_TOOLBARQ工h钮的宽度和高度都改ؓ(f)20。在上面依次d14个按钮ƈ分好l,按钮上的内容无关紧要Q只要不是空的就行了(jin)。删除系l原来的工具栏IDR_MAINFRAME?/p>
q个工具栏在昄Ӟ我们?x)用上面的位图替换各按钮?/p>
④在MainFrm.h中定义三个位囑ֈ表对象和一个函数定义:(x)
MainFrm.hQ?/span> CImageList m_imageToolBar; CImageList m_imageToolBarDisable; CImageList m_imageToolBarHot; void InitToolBar(); |
⑤在MainFrm.cpp中修改工h的设|部分:(x)
MainFrm.cppQ?/span> if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar( IDR_TOOLBAR )) //指定工具栏ID?/span> { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } InitToolBar(); //讄真彩工具?/font> |
q里要把原工h的IDQIDR_MAINFRAMEQ修改ؓ(f)新工h的IDQIDR_TOOLBARQ,再调用函数InitToolBar()讄新工h?/p>
⑥添加设|工h的函数InitToolBar()Q?/p>
void CMainFrame::InitToolBar() { CBitmap bm; //zd的工?/span> m_imageToolBar.Create( 20, 20, TRUE | ILC_COLOR24, 11, 0 ); bm.LoadBitmap( IDB_TOOLBARCOLOR ); m_imageToolBar.Add( &bm,(CBitmap*)NULL ); bm.Detach(); m_wndToolBar.GetToolBarCtrl().SetImageList( &m_imageToolBar ); //止的工?/span> m_imageToolBarDisable.Create( 20, 20, TRUE | ILC_COLOR24, 11, 0 ); bm.LoadBitmap( IDB_TOOLBARDISABLE ); m_imageToolBarDisable.Add( &bm,(CBitmap*)NULL ); bm.Detach(); m_wndToolBar.GetToolBarCtrl().SetDisabledImageList( &m_imageToolBarDisable ); //当前的工?/span> m_imageToolBarHot.Create( 20, 20, TRUE | ILC_COLOR24, 11, 0 ); bm.LoadBitmap( IDB_TOOLBARHOT ); m_imageToolBarHot.Add( &bm,(CBitmap*)NULL ); bm.Detach(); m_wndToolBar.GetToolBarCtrl().SetHotImageList( &m_imageToolBarHot ); } |
其中在Create()函数中的参数依次为按钮宽度、高度?4位位囑֒按钮个数?/p>
q样一个用24位位囄成的真彩工具栏就做好?jin),如果你的l图能力很强Q可以修?2.bmpQ按钮h很好的动感。至于各按钮的响应方法与普通工h是一L(fng)?/p>
CZE序界面Q?br>
转蝲?http://www.bttc.cn/jsj/Html/vc/wen/vcwen08.htm
客户坐标Q是指在客户区的坐标p,客户==你!哈哈你定义的坐标pR可以在现有的绘图映像模式下通过坐标变换的到你的坐标pR如你在一个映像模式坐标系下的客户坐标原点为(xQyQ,那客户坐标系的坐标换成映像模式坐标p?jin),数学问题多说了(jin)!哈?
感觉你应该问逻辑坐标Q逻辑坐标不以屏幕的像素个Cؓ(f)标准。在屏幕上是多长实际是多长。MM_LOMETRICQMM_HIMETRIC{映像模?
映像识别?逻辑单位 X和Y轴正?
MM_TEXT 1 Pixels(像素) 右下
MM_LOMETRIC 2 0.1mm 右上
MM_HIMETRIC 3 0.01mm 右上
MM_LONGLISH 4 0.1inch 右上
MM_HIENGLISH 5 0.01inch 右上
MM_TWIPS 6 1/1440inch 右上
MM_ISOTROPIC 7 Variable(x==y) 变化?
MM_ANISOTROPIC 8 Variable(x<>y) 变化?
原点 都在左上?/p>
但我q是有点不理?最后想自己写一个自定义的消息映程?虽然没有写出?但还是根据这些来猜这机制的执行原?q些
E序都是上网查到?
1.在头文g?
#define WM_MYMSG WM_USER+5//自定义一个消?br> afx_msg void OnMyMessage(WPARAM wParam, LPARAM lParam); //自定义消息的处理函数声明
2.在实现文仉?
ON_MESSAGE(WM_MYMSG, OnMyMessage)
//利用ON_MESSAGE()宏在自定义消息与其处理函数间建立映射关系
void CModelessDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
//从lParam中取出CString对象的指?q将字符串内容在IDC_MSGEDIT中显C出?br>{
CString *str;
str=(CString *)lParam;
SetDlgItemText(IDC_EDIT,*str);
}
void CModelessDlg::OnMsgBTN()
{
CString str= "自定义消息被触发?jin)?;
SendMessage(WM_MYMSG, 0, (LPARAM) &str);
//lModelessDlg自己发一个自定义的消?br>}
我的理解:它是Ҏ(gu)WM_MYMSG来确定参数的值的(wParam,lParam),对于每一个消息操作函数来定他的参数?q里的SendMessage函数把WM_MYMSG?wParam)0?lParam)&str捆绑在一起了(jin),所?在我们用消息处理函数OnMyMessage()?我们若要用到参数时我们就可以用这两个参数,在这的参C|应该不可以改变的吧,我猜?
后来看到一本书Q自定义的消息函C般带wParam,lParamq两个参敎ͼ加下面一D代码增加理解:(x)
暂时理解消息函数是通过消息(WM_)对应的参?wParam.lParam).
BOOL CServerDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_SOCKET)
{
m_sockCur = pMsg->wParam;
m_nCurMsg = pMsg->lParam;
}
return CDialog::PreTranslateMessage(pMsg);
}
通过WM_SOCKET兌 pMsg->wParam和pMsg->lParam?br> 但当我在用WSAAsyncSelect函数时没有看C的消息参?假如在这里是WM_SOCKET_READ)未与一些参数关联在一?而且q个参数q是我自定义?不是pȝ本n有的,它是用来接收消息的参数的,后来我查MSDN时发C的描q是q样?
When one of the nominated network events occurs on the specified socket s, the application's window hWnd receives message wMsg. The wParam parameter identifies the socket on which a network event has occurred. The low word of lParam specifies the network event that has occurred. The high word of lParam contains any error code. The error code be any error as defined in Winsock2.h.
Note Upon receipt of an event notification message, the WSAGetLastError function cannot be used to check the error value because the error value returned can differ from the value in the high word of lParam.
The error and event codes can be extracted from the lParam using the macros WSAGETSELECTERROR and WSAGETSELECTEVENT, defined in Winsock2.h as:
#define WSAGETSELECTERROR(lParam) HIWORD(lParam)
#define WSAGETSELECTEVENT(lParam) LOWORD(lParam)
当一个指定的|络事g发生在指定的套接字s上时,应用E序的窗口句柄接收到一条消息wMsg,wParam识别|络事g发生在哪一个套接字?lParam的低字段则指定发生的|络事g,高字D包括Q意的错误代码,错误代码在Winsock2.h文g中定?
q事件和错误可以从lParam通过调用宏WSAGETSELECTERROR ?WSAGETSELECTEVENT提取,在Winsock2.h文g中定义ؓ(f):
#define WSAGETSELECTERROR(lParam) HIWORD(lParam)
#define WSAGETSELECTEVENT(lParam) LOWORD(lParam)
可以看出WSAAsyncSelect收到的参数还是在其它地方作过兌?不然它也不会(x)有?wParam,lParam),q是我的推理,未证?
typedef UINT WPARAM;(wParam的类型,w表示WORD)
typedef LONG LPARAM;(lParam的类?l表示LONG)
实现文g:
#include "stdafx.h"http://注意也要加这?br>#include "Security.h"
unsigned int HashOf(CString Str)
{
int i, key;
key = 0;
for(i = 0; i < Str.GetLength(); i++)
{
key = ((key << 2) | (key >> 30))^(Str.GetAt(i));
}
return key;
};
//加密
CString Encrypt(CString Str)
{
return Str;
}
//解密
CString UnEncrypt(CString Str)
{
return Str;
}
创徏之后,记得在要用到q些函数的文件中包含q些文g.