??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久人妻一区精品,久久强奷乱码老熟女网站,成人久久精品一区二区三区 http://www.shnenglu.com/bestcln/category/8824.html初学VC ,是把每天所看到的整理到博客Q慢慢消化这些内宏V见证我的学习之路吧。很多都是{载?/description>zh-cnTue, 09 Jun 2009 05:24:56 GMTTue, 09 Jun 2009 05:24:56 GMT60windows消息机制 (1)http://www.shnenglu.com/bestcln/articles/87137.html极品垃圾极品垃圾Tue, 09 Jun 2009 01:19:00 GMThttp://www.shnenglu.com/bestcln/articles/87137.htmlhttp://www.shnenglu.com/bestcln/comments/87137.htmlhttp://www.shnenglu.com/bestcln/articles/87137.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/87137.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/87137.html1. H口q程

每个H口会有一个称为窗口过E的回调函数(WndProc)Q它带有四个参数Q分别ؓQ窗口句?Window Handle),消息ID(Message ID),和两个消息参?wParam, lParam), 当窗口收到消息时pȝ׃调用此窗口过E来处理消息。(所以叫回调函数Q?/p>

2 消息cd

1) pȝ定义消息(System-Defined Messages)

在SDK中事先定义好的消息,非用户定义的Q其范围在[0x0000, 0x03ff]之间Q?可以分ؓ以下三类Q?br>
1>H口消息(Windows Message)

与窗口的内部q作有关Q如创徏H口Q绘制窗口,销毁窗口等。可以是一般的H口Q也可以是Dialog,控g{?br>
如:WM_CREATE, WM_PAINT, WM_MOUSEMOVE, WM_CTLCOLOR, WM_HSCROLL...

2>命o消息(Command Message)

与处理用戯求有养I 如单击菜单项或工h或控件时Q?׃产生命o消息?br>
WM_COMMAND, LOWORD(wParam)表示菜单,工具栏按钮或控g的ID。如果是控g, HIWORD(wParam)表示控g消息cd

3> 控g通知(Notify Message)

控g通知消息Q?q是最灉|的消息格式, 其Message, wParam, lParam分别为:WM_NOTIFY, 控gIDQ指向NMHDR的指针。NMHDR包含控g通知的内容, 可以L扩展?br>
2) E序定义消息(Application-Defined Messages)

用户自定义的消息Q?对于其范围有如下规定Q?br>
WM_USER: 0x0400-0x7FFF    (ex. WM_USER+10)

WM_APP(winver>4.0): 0x8000-0xBFFF (ex.WM_APP+4)

RegisterWindowMessage: 0xC000-0xFFFF

3 消息队列(Message Queues)

Windows中有两种cd的消息队?br>
1) pȝ消息队列(System Message Queue)

q是一个系l唯一的QueueQ设备驱?mouse, keyboard)会把操作输入转化成消息存在系l队列中Q然后系l会把此消息攑ֈ目标H口所在的U程的消息队?thread-specific message queue)中等待处?br>
2) U程消息队列(Thread-specific Message Queue)

每一个GUIU程都会l护q样一个线E消息队列?q个队列只有在线E调用GDI函数时才会创建,默认不创?。然后线E消息队列中的消息会被送到相应的窗口过E?WndProc)处理.

注意Q?U程消息队列中WM_PAINTQWM_TIMER只有在Queue中没有其他消息的时候才会被处理QWM_PAINT消息q会被合q以提高效率。其他所有消息以先进先出QFIFOQ的方式被处理?/p>

4 队列消息(Queued Messages)和非队列消息(Non-Queued Messages)

1)队列消息(Queued Messages)


消息会先保存在消息队列中Q消息@环会从此队列中取消息q分发到各窗口处?br>
如鼠标,键盘消息?br>
2) 非队列消?NonQueued Messages)

消息会绕q系l消息队列和U程消息队列直接发送到H口q程被处?br>
如: WM_ACTIVATE, WM_SETFOCUS, WM_SETCURSORQ?WM_WINDOWPOSCHANGED

注意: postMessage发送的消息是队列消息,它会把消息Post到消息队列中Q?SendMessage发送的消息是非队列消息Q?被直接送到H口q程处理

5 PostMessage(PostThreadMessage), SendMessage

PostMessage:把消息放到指定窗口所在的U程消息队列中后立即q回?PostThreadMessageQ把消息攑ֈ指定U程的消息队列中后立卌回?br>
SendMessageQ直接把消息送到H口q程处理Q?处理完了才返回?/p>

6 GetMessage, PeekMessage

PeekMessage会立卌?nbsp; 可以保留消息

GetMessage在有消息时返?nbsp;会删除消?/p>

7 TranslateMessage, TranslateAccelerator

TranslateMessage: 把一个virtual-key消息转化成字W消?character message)Qƈ攑ֈ当前U程的消息队列中Q消息@环下一ơ取出处理?br>
TranslateAccelerator: 快捷键对应到相应的菜单命o。它会把WM_KEYDOWN ?WM_SYSKEYDOWN转化成快捷键表中相应的WM_COMMAND 或WM_SYSCOMMAND消息Q?然后把{化后?WM_COMMAND或WM_SYSCOMMAND直接发送到H口q程处理Q?处理完后才会q回?/p>

8(消息死锁( Message Deadlocks)

假设有线EA和BQ?现在有以下下步骤

1) U程A SendMessagel线EB, A{待消息在线EB中处理后q回

2) U程B收到了线EA发来的消息,q进行处理, 在处理过E中QB也向U程A SendMessgaeQ然后等待从Aq回?br>
因ؓ此时Q?U程A正等待从U程Bq回Q?无法处理B发来的消息, 从而导致了U程A,B怺{待Q?形成死锁。多个线E也可以形成环Ş死锁?br>
可以使用 SendNotifyMessage或SendMessageTimeout来避免出现死锁?/p>

9 BroadcastSystemMessage

我们一般所接触到的消息都是发送给H口的, 其实Q?消息的接收者可以是多种多样的,它可以是应用E序(applications), 可安装驱?installable drivers), |络讑֤(network drivers), pȝU设备驱?system-level device drivers){,

BroadcastSystemMessageq个API可以对以上系l组件发送消?/p>

极品垃圾 2009-06-09 09:19 发表评论
]]>
匈牙利表C法http://www.shnenglu.com/bestcln/articles/86625.html极品垃圾极品垃圾Wed, 03 Jun 2009 01:45:00 GMThttp://www.shnenglu.com/bestcln/articles/86625.htmlhttp://www.shnenglu.com/bestcln/comments/86625.htmlhttp://www.shnenglu.com/bestcln/articles/86625.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/86625.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/86625.html几年以前,Charles Simonyi(他后来成为微软的著名E序?设计了一U以前缀为基的命名方?q种Ҏ后来UCؓ"匈牙利表C法"以记念他.他的思想是根据每个标识符所代表的含义给它一个前~.微Y后来采用了这个思想,l每个标识符一个前~以说明它的数据类?因此,整型变量的前~是n,长整型变量是nl,字符型数l变量是ca,以及字符?以空cdl尾的字W数l?以sz为前~.q些名字可能会非常古?比如?lpszFoo表示"Foo"是一个指向以I字Wؓl尾的字W串的长整型指针.

 

q种Ҏ的优Ҏ使h能够通过变量的名字来辨别变量的类?而不比去查找它的定义.遗憾的是,q种Ҏ不仅使变量名字非常绕?而且使改变变量类型的工作变得十分艰巨.在Windows3.1?整型变量?6为宽.如果我们在开始时采用了一个整型变?但是在通过30---40个函数的计算之后,发现采用整型变量宽度不够,q时我们不仅要改变这个变量的cd,而且要改变这个变量在q?0--40个函C的名?

 

因ؓ不切实际,除了一些顽固的WindowsE序员外已经没有人再使用"匈牙利表C法"?毫无疑问,在某U场合它依然存在,但大部分人现在已l抛弃它?一般而言,输入前缀是一U糟p的x,因ؓ它把变量于其cd紧紧地绑在了一?

对于30行以下的函数Q匈牙利Ҏ一般有优势?/p>

其是对界面~程Q有优势?/p>

但对于有强烈的算法要求、尤其是有很多抽象类型的C++E序Q匈牙利Ҏ直是一个灾难?/p>

看你用在什么地斏V?/p>

现在有了很好的IDE工具,?VC,SourceInsight{?

选中变量,会自动提C告诉你它的声明和定?q样

匈牙利命名法没有很大的必要?

无非是ZE序可读性较?

实际上良好的代码书写习惯比强制用匈牙利命名法更重要.

pȝ性。整体性。可L。分c要清楚。要有注释!

 

匈牙利命名法是微软推q的一U关于变量、函数、对象、前~、宏定义{各U类型的W号的命名规范。匈牙利命名法的主要思想是:在变量和函数名中加入前缀以增qh们对E序的理解。它是由微Y内部的一个匈牙利人发起用的Q结果它在微软内部逐渐行hQƈ且推q给了全世界的Windows开发h员。下面将介绍匈牙利命名法Q后面的例子里也会尽量遵守它和上面的代码风格。还是那句话Qƈ不是要求所有的读者都要去遵守Q但是希望读者作Z个现代的软g开发h员都去遵守它?/p>

 

 

a       Array                                 数组

  b       BOOL (int)                            布尔(整数)

  by      Unsigned Char (Byte)                  无符号字W?字节)

  c       Char                                  字符(字节)

  cb      Count of bytes                        字节?/p>

  cr      Color reference value                 颜色(参??/p>

  cx      Count of x (Short)                    x的集?短整?

  dw      DWORD   (unsigned long)                 双字(无符号长整数)

  f       Flags   (usually multiple bit values)   标志(一般是有多位的数?

  fn      Function                              函数

  g_      global                                全局?/p>

  h       Handle                                句柄

  i       Integer                               整数

  l       Long                                  长整?/p>

  lp      Long pointer                          长指?/p>

  m_      Data member of a class                一个类的数据成?/p>

  n       Short int                             短整?/p>

  p       Pointer                               指针

  s       String                                字符?/p>

  sz      Zero terminated String                ?l尾的字W串

  tm      Text metric                           文本规则

  u       Unsigned int                          无符h?/p>

  ul      Unsigned long (ULONG)                 无符号长整数

  w       WORD (unsigned short)                 无符L整数

  x,y     x, y coordinates (short)              坐标?短整?/p>

  v       void                                  I?/p>

 

 

 

有关目的全局变量用g_开始,cL员变量用m_Q局部变量若函数较大则可考虑用l_用以昄说明其是局部变量?/p>

 

前缀       cd       例子

g_    全局变量       g_Servers

C     cL者结构体       CDocumentQCPrintInfo

m_   成员变量       m_pDocQm_nCustomers

 

VC常用前缀列表Q?/p>

 

前缀       cd       描述       例子

ch    char 8位字W?nbsp;   chGrade

ch    TCHAR       16位UNICODEcd字符       chName

b     BOOL       布尔变量       bEnabled

n     int    整型Q其大小由操作系l决定)       nLength

n     UINT       无符h型(其大由操作pȝ军_Q?nbsp;      nLength

w    WORD       16位无W号整型    wPos

l      LONG       32位有W号整型    lOffset

dw   DWORD       32位无W号整型       dwRange

p     *       Ambient memory model pointer 内存模块指针Q指针变?nbsp;   pDoc

lp     FAR*       长指?nbsp;      lpDoc

lpsz  LPSTR       32位字W串指针       lpszName

lpsz  LPCSTR       32位常量字W串指针       lpszName

lpsz  LPCTSTR       32位UNICODEcd帔R指针       lpszName

h     handle       Windows对象句柄       hWnd

lpfn  (*fn)()       回调函数指针 Callback Far pointer to CALLBACK function       lpfnAbort

 

Windows对象名称~写Q?/p>

 

Windows对象       例子变量       MFCc?nbsp;      例子对象

HWND    hWnd;       CWnd*       pWnd;

HDLG     hDlg;       CDialog*       pDlg;

HDC       hDC;       CDC*       pDC;

HGDIOBJ       hGdiObj;       CGdiObject*     pGdiObj;

HPEN     hPen;       CPen*       pPen;

HBRUSH hBrush;       CBrush*       pBrush;

HFONT   hFont;       CFont*       pFont;

HBITMAP       hBitmap;       CBitmap*       pBitmap;

HPALETTE       hPalette;       CPalette*       pPalette;

HRGN     hRgn;       CRgn*       pRgn;

HMENU hMenu;       CMenu*       pMenu;

HWND    hCtl;       CStatic*       pStatic;

HWND    hCtl;       CButton*       pBtn;

HWND    hCtl;       CEdit*       pEdit;

HWND    hCtl;       CListBox*       pListBox;

HWND    hCtl;       CComboBox*       pComboBox;



极品垃圾 2009-06-03 09:45 发表评论
]]>
双缓? Q?Q?/title><link>http://www.shnenglu.com/bestcln/articles/85679.html</link><dc:creator>极品垃圾</dc:creator><author>极品垃圾</author><pubDate>Mon, 25 May 2009 02:43:00 GMT</pubDate><guid>http://www.shnenglu.com/bestcln/articles/85679.html</guid><wfw:comment>http://www.shnenglu.com/bestcln/comments/85679.html</wfw:comment><comments>http://www.shnenglu.com/bestcln/articles/85679.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bestcln/comments/commentRss/85679.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bestcln/services/trackbacks/85679.html</trackback:ping><description><![CDATA[昄的图形ؓ什么会闪烁<br>  我们的绘图过E大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏q显C时是由OnPaintq行调用的。当H口׃M原因需要重l时QL先用背景色将昄区清除,然后才调用OnPaintQ而背景色往往与绘囑ֆ容反差很大,q样在短旉内背景色与显C图形的交替出现Q得显C窗口看h在闪。如果将背景刯|成NULLQ这h论怎样重绘囑Ş都不会闪了。当Ӟq样做会使得H口的显CZؕ成一团,因ؓ重绘时没有背景色对原来绘制的囑Şq行清除Q而又叠加上了新的囑Ş。有的h会说Q闪烁是因ؓl图的速度太慢或者显C的囑Ş太复杂造成的,其实q样说ƈ不对Q绘囄昄速度寚w烁的影响不是Ҏ性的。例如在OnDraw(CDC *pDC)中这样写Q?br><br> pDC->MoveTo(0,0);<br> pDC->LineTo(100,100);<br><br>  q个l图q程应该是非常简单、非常快了吧Q但是拉动窗口变化时q是会看见闪烁。其实从道理上讲Q画囄q程复杂越慢闪烁应该越,因ؓl图用的旉与用背景清除屏幕所q旉的比例越大h寚w烁的感觉会越不明显。比如:清楚屏幕旉?sl图旉也是?sQ这样在10s内的q箋重画中就要闪?ơ;如果清楚屏幕旉?s不变Q而绘图时间ؓ9sQ这?0s内的q箋重画只会闪烁一ơ。这个也可以试验Q在OnDraw(CDC *pDC)中这样写Q?br><br>for(int i=0;i<100000;i++)<br>{<br> pDC->MoveTo(0,i);<br> pDC->LineTo(1000,i);<br>}<br><br>  E序有点极端Q但是能说明问题?br><br>  说到q里可能又有说了Qؓ什么一个简单图形看h没有复杂囑Ş那么闪呢Q这是因为复杂图形占的面U大Q重L造成的反差比较大Q所以感觉上要闪得厉害一些,但是闪烁频率要低。那Z么动ȝ重画频率高,而看h却不闪?q里Q我p再次了,闪烁是什么?闪烁是反差Q反差越大,闪烁厉実뀂因为动ȝq箋两个帧之间的差异很小所以看h不闪。如果不信,可以在动ȝ每一帧中间加一张纯白的帧,不闪才怪呢? <p><font color=#0000ff>2、解军_法:</font><br>  在图形图象处理编E过E中,双缓冲是一U基本的技术。我们知?如果H体在响应WM_PAINT消息的时候要q行复杂的图形处理,那么H体在重l时׃q频的刷新而引起闪烁现象。解册一问题的有效方法就是双~冲技术?/p> <p>  因ؓH体在刷新时Q总要有一个擦除原来图象的q程OnEraseBkgndQ它利用背景色填充窗体绘囑֌Q然后在调用新的l图代码q行重绘Q这样一擦一写造成了图象颜色的反差。当WM_PAINT的响应很频繁的时候,q种反差也就发明显。于是我们就看到了闪烁现象?/p> <p>  我们会很自然的想刎ͼ<font color=#0000ff>避免背景色的填充是最直接的办法。但是那L话,H体上会变的一团糟。因为每ơ绘制图象的时候都没有原来的图象清除Q造成了图象的D留Q于是窗体重l时Q画面往往会变的ؕ七八p。所以单U的止背景重绘是不够的</font>。我们还要进行重新绘图,但要求速度很快Q于是我们想C使用<font color=#ff0000>BitBlt函数。它可以支持囑Ş块的复制Q速度很快。我们可以先在内存中作图Q然后用此函数将做好的图复制到前収ͼ同时止背景hQ这样就消除了闪?/font>。以上也是双缓冲绘囄基本的思\?/p> <p><font color=#0000ff>Q、具体步骤:<br></font><font color=#0000ff><font color=#000000>  假设我们建立了一个Draw的工E,我们要在DrawView中进行绘图操作?br><br>  在双~冲Ҏ中,首先要做的是屏蔽背景h。背景刷新其实是在响应WM_ERASEBKGND消息。我们在视类QCDrawViewQ中d对这个消息的响应Q可以看到缺省的代码如下Q?/font></font></p> <p> BOOL CDrawView::OnEraseBkgnd(CDC* pDC) <br> {<br>       //return CDrawView::OnEraseBkgnd(pDC);<br>  <font color=#0000ff>return TRUE;<br></font> }<br><br><font color=#0000ff>接下来是双缓冲的实现步骤Q?br></font><br><font color=#0000ff>Q?Q增加成员变?/font>Q在DrawView.h文g中)<br><br> //参数声明<br>  CBitmap* m_pOldBitmap;<br>   CBitmap* m_pMemBitmap; //声明内存中承载时图象的位图<br>  CDC* m_pMemDC;   //声明用于~冲作图的内存DC<br><br><font color=#0000ff>Q?Q初始化变量</font>Q在DrawView的构造函CQ?br><br>  m_pMemDC=new CDC();<br>  m_pMemBitmap=new CBitmap();<br><br><font color=#0000ff>Q?Q增加消息响应函?/font><font color=#0080ff>WM_CREATEQ?font color=#000000>在DrawView.cpp?/font>Q?br><br></font> int CDrawView::OnCreate(LPCREATESTRUCT lpCreateStruct)<br> {<br>   if (CView::OnCreate(lpCreateStruct) == -1)<br>    return -1;</p> <p><font color=#0000ff><font color=#000000>   int x=GetSystemMetrics(SM_CXSCREEN);<br>   int y=GetSystemMetrics(SM_CYSCREEN);<br><br>  CDC* pDC=GetDC();<br>  m_pMemDC->CreateCompatibleDC(pDC); //依附H口DC创徏兼容内存DC<br>  m_pMemBitmap->CreateCompatibleBitmap(pDC,x,y); //创徏兼容位图<br>   m_pOldBitmap=m_pMemDC->SelectObject(m_pMemBitmap); //位N进内存DC,原位图保存到m_pOldBitmap<br><br>   CBrush brush(RGB(255,255,255));<br>  m_pMemDC->FillRect(CRect(0,0,x,y),&brush);    //讄客户景ؓ白色<br><br>  ReleaseDC(pDC);</font></font></p> <p><font color=#0000ff><font color=#000000>  return 0;<br> }<br><font color=#0000ff>Q?Q修改OnDraw()函数</font>(DrawView.cpp?<br><br>  void CDrawView::OnDraw(CDC* pDC)<br>  {<br>   CDocument* pDoc = GetDocument();<br>   CRect rc;<br>   GetClientRect(&rc);<br>   <font color=#0000ff>DrawSomething();   //在这个函数里你可以画你想ȝ东西</font><br>   pDC->BitBlt(0,0,rc.Width(),rc.Height(),m_pMemDC,0,0,SRCCOPY);<br>    //q里是内存里面的d复制到显C备的buffer?br></font></font><font color=#0000ff><font color=#000000>  }<br><br><font color=#0000ff>Q?Q自ql图函数</font>(DrawView.cpp?<br><br>  void DrawSomething()<br>  {<br>      m_pMemDC->Rectangle(0,0,100,100);        //此处M个矩?br>       Invalidate();<br>  }<br><br><font color=#0000ff>Q?Qdelete掉new的东?/font>Q在DrawView的析构函CQ?br><br></font></font><font color=#0000ff><font color=#000000>  delete m_pBitmap;<br>     delete m_pMemDC;<br></font></font></p> <img src ="http://www.shnenglu.com/bestcln/aggbug/85679.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bestcln/" target="_blank">极品垃圾</a> 2009-05-25 10:43 <a href="http://www.shnenglu.com/bestcln/articles/85679.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC++双缓冲实现方?http://www.shnenglu.com/bestcln/articles/85673.html极品垃圾极品垃圾Mon, 25 May 2009 01:58:00 GMThttp://www.shnenglu.com/bestcln/articles/85673.htmlhttp://www.shnenglu.com/bestcln/comments/85673.htmlhttp://www.shnenglu.com/bestcln/articles/85673.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/85673.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/85673.html  因ؓH体在刷新时Q总要有一个擦除原来图象的q程OnEraseBkgndQ它利用背景色填充窗体绘囑֌Q然后在调用新的l图代码q行重绘Q这样一擦一写造成了图象颜色的反差。当WM_PAINT的响应很频繁的时候,q种反差也就发明显。于是我们就看到了闪烁现象?/p>

  我们会很自然的想刎ͼ避免背景色的填充是最直接的办法。但是那L话,H体上会变的一团糟。因为每ơ绘制图象的时候都没有原来的图象清除Q造成了图象的D留Q于是窗体重l时Q画面往往会变的ؕ七八p。所以单U的止背景重绘是不够的。我们还要进行重新绘图,但要求速度很快Q于是我们想C使用BitBlt函数。它可以支持囑Ş块的复制Q速度很快。我们可以先在内存中作图Q然后用此函数将做好的图复制到前収ͼ同时止背景hQ这样就消除了闪烁。以上也是双缓冲绘囄基本的思\?/p>

  先按普通做囄Ҏq行~程。即在视cȝOnDraw函数中添加绘图代码。在此我们绘制若q同心圆Q代码如下:
 CBCDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 CPoint ptCenter;
 CRect rect,ellipseRect;
 GetClientRect(&rect);
 ptCenter = rect.CenterPoint();
 for(int i=20;i>0;i--)
 {
      ellipseRect.SetRect(ptCenter,ptCenter);
      ellipseRect.InflateRect(i*10,i*10);
      pDC->Ellipse(ellipseRect);
 }

~译q行E序Q尝试改变窗口大,可以发现闪烁现象?/p>

  在双~冲Ҏ中,首先要做的是屏蔽背景h。背景刷新其实是在响应WM_ERASEBKGND消息。我们在视类中添加对q个消息的响应,可以看到~省的代码如下:

BOOL CMYView::OnEraseBkgnd(CDC* pDC) 
{
     return CView::OnEraseBkgnd(pDC);
}

是调用父cȝOnEraseBkgnd函数Q我们屏蔽此调用Q只ȝ接return TRUE;卛_?/p>

  下面是内存缓冲作囄步骤?/p>

 CPoint ptCenter;
 CRect rect,ellipseRect;
 GetClientRect(&rect);
 ptCenter = rect.CenterPoint();
 CDC dcMem;                                                 //用于~冲作图的内存DC
 CBitmap bmp;                                                //内存中承载时图象的位图
 dcMem.CreateCompatibleDC(pDC);              //依附H口DC创徏兼容内存DC
 bmp.CreateCompatibleBitmap(&dcMem,rect.Width(),rect.Height());//创徏兼容位图
 dcMem.SelectObject(&bmp);                         //位N择q内存DC
 dcMem.FillSolidRect(rect,pDC->GetBkColor());//按原来背景填充客户区Q不然会是黑?br> for(int i=20;i>0;i--)                                         //在内存DC上做同样的同心圆图象
 {
      ellipseRect.SetRect(ptCenter,ptCenter);
      ellipseRect.InflateRect(i*10,i*10);
      dcMem.Ellipse(ellipseRect);
 }
 pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY);//内存DC上的图象拯到前?br> dcMem.DeleteDC();                                      //删除DC
 bm.DeleteObject();                                       //删除位图

׃复杂的画图操作{入后収ͼ我们看到的是速度很快的复制操作,自然也就消除了闪烁现象?/p>

极品垃圾 2009-05-25 09:58 发表评论
]]>
VC++完成Win2000下直接读写磁盘扇?http://www.shnenglu.com/bestcln/articles/83612.html极品垃圾极品垃圾Thu, 21 May 2009 14:19:00 GMThttp://www.shnenglu.com/bestcln/articles/83612.htmlhttp://www.shnenglu.com/bestcln/comments/83612.htmlhttp://www.shnenglu.com/bestcln/articles/83612.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/83612.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/83612.html
对磁盘扇区数据的讉K

前面已经提过Q在Windows 下把所有的讑֤当作文gq行操作。如果对串口q行~程或许不少读者还比较熟悉Q对于串行端??Q可以用”COM1”?#8221;COM2”作ؓ参数调用CreateFileQ)函数Q这里的”COM1”?#8221;COM2”即以文g存放路径的方式指Z要操作的g讑֤。但是如果需要对盘的某个扇行读写,可能不少读者不会想C用CreateFileQ)函数或是不知如何使用。其实,与对串行端口的访问类|需要用与文件存放\径相cM的方式指操作的硬件设备(盘Q。但是这里ƈ不是?#8220;DISK1”?#8220;DISK2”{去标识某一块物理存在的盘。由于逻辑扇区是存在于逻辑分区上的Q因此这里需要以某种特定的格式来指定需要访问的盘逻辑分区。对于逻辑分区XQ其格式?#8221;\\.\X:”?br>
HANDLE CreateFile( LPCTSTR lpFileName,

DWORD dwDesiredAccess,

DWORD dwShareMode,

LPSECURITY_ATTRIBUTES lpSecurityAttributes,

DWORD dwCreationDisposition,

DWORD dwFlagsAndAttributes,

HANDLE hTemplateFile );


CreateFileQ)函数原型如上所C,׃讉K的是事实上已l存在的盘扇区Q因此只能以OPEN_EXISTING标志讄dwCreationDisposition参数指出要打开已经存在的文Ӟ讑֤Q。至于其他参数的使用与操作普通文件时的用法相同?br>
通过CreateFileQ)打开的是整个盘逻辑分区Q而要操作的是该分区的某些扇区Q因此还要通过SetFilePointerQ)函数以文件操作的方式把指针移到要操作的磁盘扇区开始处。SetFilePointerQ)函数原型为:

DWORD SetFilePointer(HANDLE hFile,

LONG lDistanceToMove,

PLONG lpDistanceToMoveHigh,

DWORD dwMoveMethod);


参数hFile为CreateFileQ)q回的文Ӟ讑֤Q句柄;lDistanceToMove和lpDistanceToMoveHigh指出了要讄偏移量的低端和高端部分;dwMoveMethod指出文g指针从何处开始移动,可能的选项有FILE_STARTQ从文g开始)、FILE_ENDQ从文gl尾Q和FILE_CURRENTQ从文g当前位置Q?br>
在定位到要访问的扇区开始位|后可以通过ReadFileQ)或WriteFileQ)函数实施相应的读写访问了Q具体操作与文gdq没有什么太大的差别。最后,在完成访问操作后以CloseHandleQ)关闭文g句柄释放资源Q从而完成一ơ完整的盘扇区数据讉K操作。下面给出具体的诅R写处理q程Q?br>
BOOL CDirectAccessHDDlg::WriteSectors(BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff)

// 对磁盘扇区数据的写入

{

 if (bDrive == 0) return 0;

 char devName[] = "\\\\.\\A:";

 devName[4] ='A' + bDrive - 1;

 HANDLE hDev = CreateFile(devName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

 if (hDev == INVALID_HANDLE_VALUE) return 0;

 SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);

 DWORD dwCB;

 BOOL bRet = WriteFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);

 CloseHandle(hDev);

 return bRet;

}

BOOL CDirectAccessHDDlg::ReadSectors(BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff)

// 对磁盘扇区数据的d

{

 if (bDrive == 0) return 0;

 char devName[] = "\\\\.\\A:";

 devName[4] ='A' + bDrive - 1;

 HANDLE hDev = CreateFile(devName, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

 if (hDev == INVALID_HANDLE_VALUE) return 0;

 SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);

 DWORD dwCB;

 BOOL bRet = ReadFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);

 CloseHandle(hDev);

 return bRet;

}


盘扇区数据直接d技术的应用

上一步实C对磁盘扇区数据进行读写访问的核心处理q程。在此基上可以完成一些有实用价值的应用Q例如,可以实现Ҏ定磁盘分Z指定h扇区的内Ҏ看:

if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE) {

 MessageBox("所选磁盘分Z存在Q?, "错误", MB_OK | MB_IConERROR);

 return;

}


Z方便数据的显C,可做如下处理以完成格式{换等工作Q?br>
for (DWORD i = 0; i < dwSectorNum * 512; i++) {

 sprintf(cBuf, "%s%02X ", cBuf, bBuf[i]);

 if ((i % 512) == 511)

sprintf(cBuf, "%s\r\nW?d扇区\r\n", cBuf, (int)(i / 512) + m_uFrom);

 if ((i % 16) == 15)

sprintf(cBuf, "%s\r\n", cBuf);

 else if ((i % 16) == 7)

sprintf(cBuf, "%s- ", cBuf);

}




昄l果如上图所C。另外一U应用与之类|卛_盘扇区内容的备份与恢复处理。不防病毒软g都提供这L功能Q对盘引导区内容的备䆾Q一旦硬盘引导扇病毒破坏后能够通过对备份数据的写入实现恢复。备份操作与前面的数据显C操作类|只是把读取的内容不经格式处理而直接保存到指定的文件中卛_Q?br>
file.Open(fileDlg.GetPathName(), Cfile::modeCreate | Cfile::modeReadWrite);

……

if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE) {

 MessageBox("所选磁盘分Z存在Q?, "错误", MB_OK | MB_IConERROR);

 return;

}

file.Write(bBuf, dwSectorNum * 512);

file.Close();


数据的恢复处理正好与之相反,首先打开备䆾文gq根据文仉度计要写的扇区敎ͼ然后d其内容到~存Q最后将其写入到指定扇区完成数据的恢复:

file.Open(fileDlg.GetPathName(), Cfile::modeReadWrite);

DWORD dwSectorNum = file.GetLength();

if (dwSectorNum % 512 != 0) return;

 dwSectorNum /= 512;

 unsigned char* bBuf = new unsigned char[dwSectorNum * 512];

 file.Read(bBuf, dwSectorNum * 512);

 if (WriteSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE) {

MessageBox("所选磁盘分Z存在Q?, "错误", MB_OK | MB_IConERROR);

return;

 }

 file.Close();

 delete[] bBuf;


面将要给出的最后一个应用是对磁盘数据的安全擦除。众所周知Q在操作pȝ下是通过文g理pȝ实现Ҏ件访问管理的。当删除一个文件时Q该文g的全部内容ƈ没有发生M损坏Q如果没有外部数据的覆盖Q完全可以通过各种数据恢复软g先前删除的文g恢复出来。但在军工、政府等Ҏ的涉密行业、部门中Q要求的是数据的d删除Q即l删除过的数据是不可q行再恢复处理的。ؓ了确保磁盘数据的可靠清空Q可以对每一个扇区写入全1后再写入?。之所以多ơ写入数据,是因Zơ写入只能防止数据恢复Y件的恢复处理。如果覆盖次C多的化,通过一U被U做“盘攑֤?#8221;的特DA器仍能够以物理的Ҏ先前删除的数据恢复出来Q因此这里需要对扇区多次重复写入数据Q反复次数越多擦除效果越好。下面是q部分的具体实现代码Q?br>
unsigned char bBuf[512];

UINT i = 0;

BOOL bRet = TRUE;

while (m_bAllDisk){

 memset(bBuf, 0xFF, sizeof(bBuf));

 bRet = WriteSectors(uDiskID, i, 1, bBuf);

 memset(bBuf, 0, sizeof(bBuf));

 bRet = WriteSectors(uDiskID, i, 1, bBuf);

 if (bRet == FALSE){

if (i == 0)

 MessageBox("所选磁盘分Z存在Q?, "错误", MB_OK | MB_IConERROR);

else

 MessageBox("盘数据擦除完毕Q?, "错误", MB_OK | MB_IConERROR);

 return;

 }

 i++;

}




本文仅对盘扇区内容的直接读写方法做了介lƈl出了扇区数据内容的昄、备份与恢复、磁盘数据的d擦除{几个主要的应用作了介绍。读者可以根据需要实现其他的应用如利用磁盘扇区内容进行n份认证、数据隐藏、磁盘删除数据的恢复{。本文所q程序代码在Windows 2000 Professional + SP4下由Microsoft Visual C++ 6.0~译通过?


极品垃圾 2009-05-21 22:19 发表评论
]]>
UpdateData()http://www.shnenglu.com/bestcln/articles/83607.html极品垃圾极品垃圾Thu, 21 May 2009 14:14:00 GMThttp://www.shnenglu.com/bestcln/articles/83607.htmlhttp://www.shnenglu.com/bestcln/comments/83607.htmlhttp://www.shnenglu.com/bestcln/articles/83607.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/83607.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/83607.htmlUpdateData()

对于可以接收数据的控Ӟ如编辑控件来_UpdateData()函数臛_重要。当控g内容发生变化Ӟ对应的控件变量的值ƈ没有跟着变化Q同

P当控件变量值变化时Q控件内容也不会跟着变?br>UpdateData()函数是解决q个问题的?/p>

UpdateData(true);把控件内容装入控件变?br>UpdateData(false);用控件变量的值更新控?/p>

如:有编辑控件IDC_EDIT1Q对应的变量为字W串m_Edit1Q?br>1、修改变量值ƈ昄在控件中Q?br>m_Edit1 = _T("l果?0");
UpdateData(false);
2、读取控件的值到变量中:
用ClassWizard为IDC_EDIT1dEN_CHANGE消息处理函数Q?br>void CEditView::OnChangeEdit1()
{
    UpdateData(true);
}



极品垃圾 2009-05-21 22:14 发表评论
]]>
定时?/title><link>http://www.shnenglu.com/bestcln/articles/83606.html</link><dc:creator>极品垃圾</dc:creator><author>极品垃圾</author><pubDate>Thu, 21 May 2009 14:08:00 GMT</pubDate><guid>http://www.shnenglu.com/bestcln/articles/83606.html</guid><wfw:comment>http://www.shnenglu.com/bestcln/comments/83606.html</wfw:comment><comments>http://www.shnenglu.com/bestcln/articles/83606.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bestcln/comments/commentRss/83606.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bestcln/services/trackbacks/83606.html</trackback:ping><description><![CDATA[<strong><font color=#006699>一、定时器的基本用方?br><br></font></strong>在编E时Q会l常使用到定时器。用定时器的方法比较简单,通常告诉WINDOWS一个时间间隔,然后WINDOWS以此旉间隔周期性触发程序。通常有两U方法来实现Q发送WM_TIMER消息和调用应用程序定义的回调函数?br><br><font color=#0066ff>1.1 用WM_TIMER来设|定时器</font><br><br>先请看SetTimerq个API函数的原? <pre>UINT_PTR SetTimer( HWND hWnd, // H口句柄 UINT_PTR nIDEvent, // 定时器IDQ多个定时器Ӟ可以通过该ID判断是哪个定时器 UINT uElapse, // 旉间隔,单位为毫U? TIMERPROC lpTimerFunc // 回调函数 ); </pre> 例如 <pre>SetTimer(m_hWnd,1,1000,NULL); //一?U触发一ơ的定时?/pre> 在MFCE序中SetTimer被封装在CWndcMQ调用就不用指定H口句柄了,例如:<br> <pre>UINT SetTimer(1,100,NULL); </pre> 函数反回值就是第一个参数?Q表C此定时器的ID受?br><br>W二个参数表C{待100毫秒旉再重新处理一ơ。第三个参数在这U方法中一般用NULL?br><strong>注意Q?/strong>讄W二个参数时要注意,如果讄的等待时间比处理旉短,E序׃出问题了?br><br><font color=#0066ff>1.2 调用回调函数</font><br><br>此方法首先写一个如下格式的回调函数<br> <pre>void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime);</pre> 然后再用SetTimer(1,100,TimerProc)函数来徏一个定时器Q第三个参数是回调函数地址?br><br><strong><font color=#006699>二、多个定时器的实C应用</font></strong><br><br>我们在安装定时器旉为其指定了IDQ用多个定时器Ӟ该ID发挥作用了?br>不用MFCӞ当接收到WM_TIMER消息QWPARAM wParam中的g是该定时器的ID<br>使用MFC时就更简单了Q我们ؓ其增加WM_TIME的消息处理函数OnTimer卛_Q请看如下例? <pre>void CTimerTestDlg::OnTimer(UINT nIDEvent) { switch (nIDEvent) { case 24: ///处理ID?4的定时器 Draw1(); break; case 25: ///处理ID?5的定时器 Draw2(); break; } CDialog::OnTimer(nIDEvent); }</pre> 当你用回调函数时Q我们可以根据nTimerid的值来判断是哪个定时器Q例? <pre>void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime) { switch(nTimerid) { case 1: ///处理ID?的定时器 Do1(); break; case 2: ///处理ID?的定时器 Do2(); break; } }</pre> <font color=#006699><strong>三、取消定时器</strong></font><br><br>不再使用定时器后Q我们应该调用KillTimer来取消定ӞKillTimer的原型如?br> <pre>BOOL KillTimer( HWND hWnd, // H口句柄 UINT_PTR uIDEvent // ID );</pre> 在MFCE序中我们可以直接调用KillTimer(int nIDEvent)来取消定时器?br><br>本文提供的例子代码在q行时就可以看到两个定时器都在工作,而且W一个在q行10ơ后׃被KILL掉?br> <img src ="http://www.shnenglu.com/bestcln/aggbug/83606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bestcln/" target="_blank">极品垃圾</a> 2009-05-21 22:08 <a href="http://www.shnenglu.com/bestcln/articles/83606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SetTimerhttp://www.shnenglu.com/bestcln/articles/83604.html极品垃圾极品垃圾Thu, 21 May 2009 13:20:00 GMThttp://www.shnenglu.com/bestcln/articles/83604.htmlhttp://www.shnenglu.com/bestcln/comments/83604.htmlhttp://www.shnenglu.com/bestcln/articles/83604.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/83604.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/83604.htmlTimer事gQ即定时器事Ӟ是在游戏~程中,l常使用的一个事件。借助它可以生定时执行动作的效果。这文章,和大家一h讨一下如何用SetTimerQ)函数?
1、SetTimer定义在那里?

SetTimer表示的是定义个定时器。根据定义指定的H口Q在指定的窗口(CWndQ中实现OnTimer事gQ这P可以相应事件了?

SetTimer有两个函数。一个是全局的函?:SetTimer()

UINT SetTimer(
HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure
);

其中hWnd 是指向CWnd的指针,卛_理Timer事g的窗口类。说道窗口类QCWndQ,我们有必要来看一下CWnd的承情况:CWnd有以下子c:CFrameWnd,CDialog,CView,CControlBar{类。这也意呌些类中都可以定义SetTimer事g?

同时QSetTimerQ)在CWnd中也有定义,即SetTimerQ)是CWnd的一个成员函数。CWnd的子cd以调用该函数Q来讄触发器?

UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) );

参数含义Q?

nIDEvent:是指讄q个定时器的iDQ即w䆾标志Q这样在OnTimerQ)事g中,才能Ҏ不同的定时器Q来做不同的事g响应。这个ID是一个无W号的整型?

nElapse

是指旉延迟。单位是毫秒。这意味着Q每隔nElapse毫秒pȝ调用一ơOntimerQ)?

void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD)

Specifies the address of the application-supplied TimerProc callback function that processes the WM_TIMER messages. If this parameter is NULL, the WM_TIMER messages are placed in the application’s message queue and handled by the CWnd object?

意思是Q指定应用程序提供的TimerProc回调函数的地址Q来处里q个Timer事g。如果是NULLQ处理这个Timer事g的定义这个Timer的CWnd对象。他WM_TIMER消息传递给q个对象Q通过实现q个对象的OnTimerQ)事g来处理这个Timer事g?

所以,一般情况下Q我们将q个D为NULLQ有讄该定时器的对象中的OnTimerQ)函数来处理这个事件?

同样的,我们再看看KillTimerQ)和OnTimerQ)的定?

KillTimer同SetTimerQ)一P他也有两个,一个是全局?:KillTimer(),另一个是CWnd的一个函数。他的声明如下:



//全局函数

BOOL KillTimer(
HWND hWnd, // handle of window that installed timer
UINT uIDEvent // timer identifier
);

//CWnd函数

BOOL KillTimer( int nIDEvent );

q两个函数表C的意思是iD为nIDEVENT的定时器U走。其不再作用。其用法如同SetTimerQ)一栗?

再看看OnTimerQ)

CWnd::OnTimer
afx_msg void OnTimer( UINT nIDEvent );

ontimerQ)是响应CWnd对象产生的WM_Timer消息。nIDEvent表示要响应TIMER事g的ID?

二、Timer事g的用:

׃上的分析Q我们应该很清楚Q如何来使用Timer事g。假定我们在视图上画一个渐变的动画。我们首先在菜单栏上d一个菜单项Q给q个菜单d命o响应Q?

pView->SetTimer(1,1000,NULL);//pView是视囄的指针,q里是在视图cd中设|一个定时器?

d完毕Q再l视囄d一个WM_Timer事g的相应。在OnTimerQ)函数中编写汉书,q行相应?

如此Q就能做出动甅R?


极品垃圾 2009-05-21 21:20 发表评论
]]>
MFCl图Q{载)http://www.shnenglu.com/bestcln/articles/83189.html极品垃圾极品垃圾Sun, 17 May 2009 08:22:00 GMThttp://www.shnenglu.com/bestcln/articles/83189.htmlhttp://www.shnenglu.com/bestcln/comments/83189.htmlhttp://www.shnenglu.com/bestcln/articles/83189.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/83189.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/83189.html阅读全文

极品垃圾 2009-05-17 16:22 发表评论
]]>
什么是U性插值原?什么是双线性插? http://www.shnenglu.com/bestcln/articles/82865.html极品垃圾极品垃圾Wed, 13 May 2009 12:29:00 GMThttp://www.shnenglu.com/bestcln/articles/82865.htmlhttp://www.shnenglu.com/bestcln/comments/82865.htmlhttp://www.shnenglu.com/bestcln/articles/82865.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/82865.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/82865.html单比?
原来的数值序列:0Q?0Q?0Q?0Q?0
U性插gơؓQ?Q?Q?0Q?5Q?0Q?5Q?0Q?5Q?0
卌为其变化Q增减)是线形的Q可以在坐标图上d一条直U?
在数码相机技术中Q这些数值可以代表组成一张照片的不同像素点的色彩、色度等指标?/p>

 

Z方便理解Q先考虑一l情况下的线性插?
对于一个数列cQ我们假设c[a]到c[a+1]之间是线性变化的
那么对于点数x(a<=x<a+1)Qc(x)=c[a+1]*(x-a)+c[a]*(1+a-x);
q个好理解吧Q?

把这U插值方式扩展到二维情况
对于一个二l数lcQ我们假讑֯于Q意一个QҎi,c(a,i)到c(a+1,i)之间是线性变化的,c(i,b)到c(i,b+1)之间也是U性变化的(a,b都是整数)
那么对于点数的坐标(x,y)满(a<=x<a+1,b<=y<b+1)Q我们可以先分别求出c(x,b)和c(x,b+1):
c(x,b) = c[a+1]*(x-a)+c[a]*(1+a-x);
c(x,b+1) = c[a+1][b+1]*(x-a)+c[a][b+1]*(1+a-x);
好,现在已经知道c(x,b)和c(x,b+1)了,而根据假设c(x,b)到c(x,b+1)也是U性变化的Q所?
c(x,y) = c(x,b+1)*(y-b)+c(x,b)*(1+b-y)
q就是双U性插|



极品垃圾 2009-05-13 20:29 发表评论
]]>
2ơ插?/title><link>http://www.shnenglu.com/bestcln/articles/82861.html</link><dc:creator>极品垃圾</dc:creator><author>极品垃圾</author><pubDate>Wed, 13 May 2009 11:50:00 GMT</pubDate><guid>http://www.shnenglu.com/bestcln/articles/82861.html</guid><wfw:comment>http://www.shnenglu.com/bestcln/comments/82861.html</wfw:comment><comments>http://www.shnenglu.com/bestcln/articles/82861.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bestcln/comments/commentRss/82861.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bestcln/services/trackbacks/82861.html</trackback:ping><description><![CDATA[<p><font face=宋体> </p> <p align=left><span>囑փ的双U性插值放大算法中Q目标图像中新创造的象素|是由源图像位|在它附q的<span>2*2</span>区域<span>4</span>个邻q象素的值通过加权q_计算得出的。双U性内插值算法放大后的图像质量较高,不会出现像素gq箋的的情况。然而次法h低通o波器的性质Q高频分量受损Q所以可能会使图像轮廓在一定程度上变得模糊?/span></p> <p align=center><span><a title="The four red dots show the data points and the green dot is the point at which we want to interpolate." ></a></span></p> <h2><span><span><span><img height=367 alt="" src="mhtml:file://F:\c盘\目前的工?--前面板制作\|页摘要\双线性插值图像放?~小法 - 枫\ - CSDNBlog.mht!http://p.blog.csdn.net/images/p_blog_csdn_net/Breathomn/EntryImages/20090306/image002.jpg" width=384></span></span></span></h2> <h2><span><span><span><span>?</span></span></span></span></h2> <h2><span><span><span>X</span><span>方向的线性插?/span></span></span></h2> <p align=left><span>对于标准的双U性差值算法,<span>X</span>方向的线性插|</span></p> <p align=left><span><img height=40 alt="" src="mhtml:file://F:\c盘\目前的工?--前面板制作\|页摘要\双线性插值图像放?~小法 - 枫\ - CSDNBlog.mht!http://p.blog.csdn.net/images/p_blog_csdn_net/Breathomn/EntryImages/20090306/image003.gif" width=541>[</span><span>通用<span>1]</span></span></p> <p align=left><span><img height=39 alt="" src="mhtml:file://F:\c盘\目前的工?--前面板制作\|页摘要\双线性插值图像放?~小法 - 枫\ - CSDNBlog.mht!http://p.blog.csdn.net/images/p_blog_csdn_net/Breathomn/EntryImages/20090306/image004.gif" width=541>[</span><span>通用<span>2]</span></span></p> <p align=left><span>具体到我们所实现的算法中Q我们Q11、Q12、Q21、Q22为光栅上盔R的四点,即P只能落于q四点其中一点上?#916;col是当前像素离像素所属区域原点的水^距离Q比如图2Q各U不同的颜色代表一个区域,区域原点为区域左上角的像素?</span></p> <p align=left> </p> <p align=left><span>δ R2 = Color Q22 −Color Q12 ?#916;col+Color Q12 ?56 (1) </span></p> <p align=left><span>δ R1 = Color Q21 −Color Q11 ?#916;col+Color Q11 ?56 (2) </span></p> <p align=left> </p> <p align=left><span>其中Q?#916;col=(DestColNumber?(SrcWidth?)/DestWidth))&255Q?Color(X)表示点X的颜Ԍ具体法使用的是24位真彩色格式?/span></p> <h2><span><span><span>Y</span><span>方向的线性插?/span></span></span></h2> <p align=left><span>做完<span>X</span>方向的插值后再做<span>Y</span>方向的插|对于一般情况,有:</span></p> <p align=left><span><span><img alt="" src="mhtml:file://F:\c盘\目前的工?--前面板制作\|页摘要\双线性插值图像放?~小法 - 枫\ - CSDNBlog.mht!http://p.blog.csdn.net/images/p_blog_csdn_net/Breathomn/EntryImages/20090306/image011.gif">     </span>[</span><span>通用<span>3]</span></span></p> <p align=left><span><span>而我们的具体法中,Y方向的线性插值方法如(3)所C?#916;row是当前像素离像素所属区域原点的垂直距离Q比如图2Q各U不同的颜色代表一个区域,区域原点为区域左上角的像素?</span></span></p> <p align=left> </p> <p align=left><span><span>Color P = δ R2 ?56+ δ R2 −δ R1 ?#916;row ?6 (3) </span></span></p> <p align=left> </p> <p align=left><span><span>其中Q?#916;row=(DestRowNumber?(SrcHeight?)/DestHeight))&255Q由于前面ؓ了便于计左UM16位,因此最后需要右U?6位保持匹配?/span></span></p> <h2><span><span><span><span><span>法描述</span></span></span></span></span></h2> <p align=left><span><span><span><span><span><span><span>c?C 伪码如下Q?/span></span></span></span></span></span></span></p> <h2></h2> <p align=left><span><span> <div nogutter?> <div> <div><a onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;" href="file:///F:/c?目前的工?--前面板制?|页摘要/双线性插值图像放?~小法%20-%20枫\%20-%20CSDNBlog.mht#">view plain</a><a onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="file:///F:/c?目前的工?--前面板制?|页摘要/双线性插值图像放?~小法%20-%20枫\%20-%20CSDNBlog.mht#">copy to clipboard</a><a onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;" href="file:///F:/c?目前的工?--前面板制?|页摘要/双线性插值图像放?~小法%20-%20枫\%20-%20CSDNBlog.mht#">print</a><a onclick="dp.sh.Toolbar.Command('About',this);return false;" href="file:///F:/c?目前的工?--前面板制?|页摘要/双线性插值图像放?~小法%20-%20枫\%20-%20CSDNBlog.mht#">?</a></div> </div> <ol> <li><span><span>for</span><span> (目标囑փW一行的像素++)      </span></span></li> <li><span>{      </span></li> <li><span>    </span><span>// 源图像上Q12, Q22, Q11, Q21的选取见下一?nbsp;   </span><span>  </span></span></li> <li><span>    获取源图像Q12, Q22, Q11, Q21的颜?      </span></li> <li><span>     </span></li> <li><span>    </span><span>// X 方向的插?nbsp;   </span><span>  </span></span></li> <li><span>    δ(R2) = (Color(Q22) - Color(Q12)) * δcol+ Color(Q12) * 256;      </span></li> <li><span>    δ(R1) = (Color(Q21) - Color(Q11)) * δcol+ Color(Q11) * 256;      </span></li> <li><span>     </span></li> <li><span>    </span><span>// 保存 δ(R1)C个时数l,因ؓ下一行的δ(R2){于q一行的δ(R1)    </span><span>  </span></span></li> <li><span>    temp[i++] = δ(R1);      </span></li> <li><span>     </span></li> <li><span>    </span><span>// Y 方向的插?nbsp;   </span><span>  </span></span></li> <li><span>    Color(P) = (δ(R2) * 256 + (δ(R2) - δ(R1)) *δrow) >> 16;      </span></li> <li><span>     </span></li> <li><span>    ?nbsp;P 输出到目标位图中?nbsp;     </span></li> <li><span>}      </span></li> <li><span>     </span></li> <li><span>for</span><span> (目标囑փW二行到最末行)      </span></span></li> <li><span>{      </span></li> <li><span>    </span><span>for</span><span> (行上的像?+)      </span></span></li> <li><span>    {      </span></li> <li><span>        </span><span>// 源图像上Q12, Q22, Q11, Q21的选取见下一?nbsp;   </span><span>  </span></span></li> <li><span>        获取源图像Q12, Q22, Q11, Q21的颜?      </span></li> <li><span>     </span></li> <li><span>        </span><span>// X 方向的插?nbsp;   </span><span>  </span></span></li> <li><span>        δ(R2) = temp[i++]; </span><span>// 下一行的δ(R2){于上一行的δ(R1)    </span><span>  </span></span></li> <li><span>        δ(R1) = (Color(Q21) - Color(Q11)) *δcol+ Color(Q11) * 256;      </span></li> <li><span>     </span></li> <li><span>        </span><span>// 保存 δ(R1)C个时数l,因ؓ下一行的δ(R2){于q一行的δ(R1)    </span><span>  </span></span></li> <li><span>        temp[i++] = δ(R1);      </span></li> <li><span>     </span></li> <li><span>        </span><span>// Y 方向的插?nbsp;   </span><span>  </span></span></li> <li><span>        Color(P) = (δ(R2) * 256 + (δ(R2) - δ(R1)) * δrow) >> 16;      </span></li> <li><span>     </span></li> <li><span>        ?nbsp;P 输出到目标位图中?nbsp;     </span></li> <li><span>    }      </span></li> <li><span>}    </span></li> </ol> </div> <p><textarea name=code rows=15 cols=50>for (目标囑փW一行的像素++) { // 源图像上Q12, Q22, Q11, Q21的选取见下一? 获取源图像Q12, Q22, Q11, Q21的颜? // X 方向的插? δ(R2) = (Color(Q22) - Color(Q12)) * δcol+ Color(Q12) * 256; δ(R1) = (Color(Q21) - Color(Q11)) * δcol+ Color(Q11) * 256; // 保存 δ(R1)C个时数l,因ؓ下一行的δ(R2){于q一行的δ(R1) temp[i++] = δ(R1); // Y 方向的插? Color(P) = (δ(R2) * 256 + (δ(R2) - δ(R1)) *δrow) >> 16; ?P 输出到目标位图中? } for (目标囑փW二行到最末行) { for (行上的像?+) { // 源图像上Q12, Q22, Q11, Q21的选取见下一? 获取源图像Q12, Q22, Q11, Q21的颜? // X 方向的插? δ(R2) = temp[i++]; // 下一行的δ(R2){于上一行的δ(R1) δ(R1) = (Color(Q21) - Color(Q11)) *δcol+ Color(Q11) * 256; // 保存 δ(R1)C个时数l,因ؓ下一行的δ(R2){于q一行的δ(R1) temp[i++] = δ(R1); // Y 方向的插? Color(P) = (δ(R2) * 256 + (δ(R2) - δ(R1)) * δrow) >> 16; ?P 输出到目标位图中? } } </textarea> </span></span></p> <p> </p> <p align=left> </p> <h2><span><span><span>法?/span><span>Q12, Q22, Q11, Q21</span><span>的选取</span></span></span></h2> <p> </p> <p align=left><span>我们以放大两倍ؓ例,说明选取Q12, Q22, Q11, Q21的过E。源囑փ3*3区域攑֤为目标区?*6区域。设以下为目标图像:</span></p> <div> <table cellSpacing=0 cellPadding=0 border=1> <tbody> <tr> <td width=31> <p align=center><span><span>A</span></span></p> </td> <td width=31> <p align=center><span><span>A</span></span></p> </td> <td width=31> <p align=center><span><span>B</span></span></p> </td> <td width=31> <p align=center><span><span>B</span></span></p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> </tr> <tr> <td width=31> <p align=center><span><span>A</span></span></p> </td> <td width=31> <p align=center><span><span>A</span></span></p> </td> <td width=31> <p align=center><span><span>B</span></span></p> </td> <td width=31> <p align=center><span><span>B</span></span></p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span><span>C</span></span></p> </td> <td width=31> <p align=center><span><span>C</span></span></p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span><span>C</span></span></p> </td> <td width=31> <p align=center><span><span>C</span></span></p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span><span>D</span></span></p> </td> <td width=31> <p align=center><span><span>D</span></span></p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span><span>D</span></span></p> </td> <td width=31> <p align=center><span><span>D</span></span></p> </td> </tr> </tbody> </table> </div> <div>?</div> <p align=left><span>目标囑փ<span>A</span>像素区域对应?span>Q21</span>Q?span>Q22</span>Q?span>Q11</span>Q?span>Q12</span>Q以U色区域为原点向右下Ҏ展的<span>2*2</span>区域?/span></p> <div> <table cellSpacing=0 cellPadding=0 border=1> <tbody> <tr> <td width=35> <p align=center><span><span>Q21</span></span></p> </td> <td width=35> <p align=center><span><span>Q22</span></span></p> </td> <td width=31> <p align=center><span></span> </p> </td> </tr> <tr> <td width=35> <p align=center><span><span>Q11</span></span></p> </td> <td width=35> <p align=center><span><span>Q12</span></span></p> </td> <td width=31> <p align=center><span></span> </p> </td> </tr> <tr> <td width=35> <p align=center><span><span></span></span> </p> </td> <td width=35> <p align=center><span></span> </p> </td> <td width=31> <p align=center><span></span> </p> </td> </tr> </tbody> </table> </div> <div>?</div> <p align=left><span>目标囑փ<span>B</span>像素区域对应?span>Q21</span>Q?span>Q22</span>Q?span>Q11</span>Q?span>Q12</span>Q以蓝色区域为原点向右下Ҏ展的<span>2*2</span>区域?/span></p> <div> <table cellSpacing=0 cellPadding=0 border=1> <tbody> <tr> <td width=31> <p><span></span> </p> </td> <td width=35> <p align=center><span><span>Q21</span></span></p> </td> <td width=35> <p align=center><span><span>Q22</span></span></p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=35> <p align=center><span><span>Q11</span></span></p> </td> <td width=35> <p align=center><span><span>Q12</span></span></p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=35> <p align=center><span></span> </p> </td> <td width=35> <p align=center><span></span> </p> </td> </tr> </tbody> </table> </div> <div>?</div> <p align=left><span>目标囑փ<span>C</span>像素区域对应?span>Q21</span>Q?span>Q22</span>Q?span>Q11</span>Q?span>Q12</span>Q以l色区域为原点向右下Ҏ展的<span>2*2</span>区域?/span></p> <div> <table cellSpacing=0 cellPadding=0 border=1> <tbody> <tr> <td width=31> <p><span></span> </p> </td> <td width=35> <p align=center><span></span> </p> </td> <td width=35> <p align=center><span></span> </p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=35> <p align=center><span><span>Q21</span></span></p> </td> <td width=35> <p align=center><span><span>Q22</span></span></p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=35> <p align=center><span><span>Q11</span></span></p> </td> <td width=35> <p align=center><span><span>Q12</span></span></p> </td> </tr> </tbody> </table> </div> <div>?</div> <p align=left><span>目标囑փ<span>D</span>像素区域对应?span>Q21</span>Q?span>Q22</span>Q?span>Q11</span>Q?span>Q12</span>Q目标图像处于最后两行的边界情况Q将<span>Q21</span>Q?span>Q22</span>Q?span>Q11</span>Q?span>Q12</span>q四个点的DZ栗?/span></p> <div> <table cellSpacing=0 cellPadding=0 border=1> <tbody> <tr> <td width=31> <p><span></span> </p> </td> <td width=35> <p align=center><span></span> </p> </td> <td width=119> <p align=center><span></span> </p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=35> <p align=center><span></span> </p> </td> <td width=119> <p align=center><span></span> </p> </td> </tr> <tr> <td width=31> <p align=center><span></span> </p> </td> <td width=35> <p align=center><span></span> </p> </td> <td width=119> <p align=center><span><span>Q11=Q12=Q22=Q21</span></span></p> </td> </tr> </tbody> </table> </div> <div>?</div> <p> <p> </p> <p align=left><span><img height=906 alt="" src="mhtml:file://F:\c盘\目前的工?--前面板制作\|页摘要\双线性插值图像放?~小法 - 枫\ - CSDNBlog.mht!http://p.blog.csdn.net/images/p_blog_csdn_net/Breathomn/EntryImages/20090306/flow1.jpg" width=532></span></p> <p align=left><span><img height=888 alt="" src="mhtml:file://F:\c盘\目前的工?--前面板制作\|页摘要\双线性插值图像放?~小法 - 枫\ - CSDNBlog.mht!http://p.blog.csdn.net/images/p_blog_csdn_net/Breathomn/EntryImages/20090306/flow2.jpg" width=529></span></p> <p> </p> <h2><span><span><span>E序程?/span></span></span></h2> <p align=left><span>程囑֏边虚U框中ؓ相关q程的注解?/span></p> </font> <img src ="http://www.shnenglu.com/bestcln/aggbug/82861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bestcln/" target="_blank">极品垃圾</a> 2009-05-13 19:50 <a href="http://www.shnenglu.com/bestcln/articles/82861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用数据cd使用转换详解http://www.shnenglu.com/bestcln/articles/82729.html极品垃圾极品垃圾Tue, 12 May 2009 12:25:00 GMThttp://www.shnenglu.com/bestcln/articles/82729.htmlhttp://www.shnenglu.com/bestcln/comments/82729.htmlhttp://www.shnenglu.com/bestcln/articles/82729.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/82729.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/82729.html
我们先定义一些常见类型变量借以说明

int i = 100;
long l = 2001;
float f=300.2;
double d=12345.119;
char username[]="E佩?;
char temp[200];
char *buf;
CString str;
_variant_t v1;
_bstr_t v2;

一、其它数据类型{换ؓ字符?/strong>

  • 短整?int)
    itoa(i,temp,10);///i转换为字W串攑օtemp?最后一个数字表C十q制
    itoa(i,temp,2); ///按二q制方式转换
  • 长整?long)
    ltoa(l,temp,10);
  • 点?float,double)
    用fcvt可以完成转换,q是MSDN中的例子:
    int decimal, sign;
    char *buffer;
    double source = 3.1415926535;
    buffer = _fcvt( source, 7, &decimal, &sign );
    q行l果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
    decimal表示数点的位置,sign表示W号:0为正敎ͼ1?
  • CString变量
    str = "2008北京奥运";
    buf = (LPSTR)(LPCTSTR)str;
  • BSTR变量
    BSTR bstrValue = ::SysAllocString(L"E序?);
    char * buf = _com_util::ConvertBSTRToString(bstrValue);
    SysFreeString(bstrValue);
    AfxMessageBox(buf);
    delete(buf);
  • CComBSTR变量
    CComBSTR bstrVar("test");
    char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
    AfxMessageBox(buf);
    delete(buf);
  • _bstr_t变量
    _bstr_tcd是对BSTR的封装,因ؓ已经重蝲?操作W,所以很Ҏ使用
    _bstr_t bstrVar("test");
    const char *buf = bstrVar;///不要修改buf中的内容
    AfxMessageBox(buf);

  • 通用Ҏ(针对非COM数据cd)
    用sprintf完成转换
    char  buffer[200];
        char  c = '1';
        int   i = 35;
        long  j = 1000;
        float f = 1.7320534f;
        sprintf( buffer, "%c",c);
        sprintf( buffer, "%d",i);
        sprintf( buffer, "%d",j);
        sprintf( buffer, "%f",f);
        

二、字W串转换为其它数据类?/font>
strcpy(temp,"123");

  • 短整?int)
    i = atoi(temp);
  • 长整?long)
    l = atol(temp);
  • 点(double)
    d = atof(temp);
  • CString变量
    CString name = temp;
  • BSTR变量
    BSTR bstrValue = ::SysAllocString(L"E序?);
    ...///完成对bstrValue的?br>SysFreeString(bstrValue);
  • CComBSTR变量
    CComBSTRcd变量可以直接赋?br>CComBSTR bstrVar1("test");
    CComBSTR bstrVar2(temp);
  • _bstr_t变量
    _bstr_tcd的变量可以直接赋?br>_bstr_t bstrVar1("test");
    _bstr_t bstrVar2(temp);

三、其它数据类型{换到CString
使用CString的成员函数Format来{?例如:

  • 整数(int)
    str.Format("%d",i);
  • 点?float)
    str.Format("%f",i);
  • 字符串指?char *){已l被CString构造函数支持的数据cd可以直接赋?br>str = username;
  • 对于Format所不支持的数据cdQ可以通过上面所说的关于其它数据cd转化到char *的方法先转到char *Q然后赋值给CString变量?br>

四、BSTR、_bstr_t与CComBSTR

  • CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封?BSTR?2位指?但ƈ不直接指向字串的~冲区?br>char *转换到BSTR可以q样:
    BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
    SysFreeString(bstrValue);
    反之可以使用
    char *p=_com_util::ConvertBSTRToString(b);
    delete p;
    具体可以参考一Q二D落里的具体说明?br>
    CComBSTR与_bstr_t对大量的操作W进行了重蝲Q可以直接进?,!=,=={操作,所以用非常方ѝ?br>特别是_bstr_t,大家使用它?br>

 

五、VARIANT 、_variant_t ?COleVariant

  • VARIANT的结构可以参考头文gVC98\Include\OAIDL.H中关于结构体tagVARIANT的定义?br>对于VARIANT变量的赋|首先lvt成员赋|指明数据cdQ再对联合结构中相同数据cd的变量赋|举个例子Q?br>VARIANT va;
    int a=2001;
    va.vt=VT_I4;///指明整型数据
    va.lVal=a; ///赋?br>
    对于不马上赋值的VARIANTQ最好先用Void VariantInit(VARIANTARG FAR* pvarg);q行初始?其本质是vt讄为VT_EMPTY,下表我们列Dvt与常用数据的对应关系:

    Byte bVal; // VT_UI1.
    Short iVal; // VT_I2.
    long lVal; // VT_I4.
    float fltVal; // VT_R4.
    double dblVal; // VT_R8.
    VARIANT_BOOL boolVal; // VT_BOOL.
    SCODE scode; // VT_ERROR.
    CY cyVal; // VT_CY.
    DATE date; // VT_DATE.
    BSTR bstrVal; // VT_BSTR.
    DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL.
    IUnknown FAR* punkVal; // VT_UNKNOWN.
    IDispatch FAR* pdispVal; // VT_DISPATCH.
    SAFEARRAY FAR* parray; // VT_ARRAY|*.
    Byte FAR* pbVal; // VT_BYREF|VT_UI1.
    short FAR* piVal; // VT_BYREF|VT_I2.
    long FAR* plVal; // VT_BYREF|VT_I4.
    float FAR* pfltVal; // VT_BYREF|VT_R4.
    double FAR* pdblVal; // VT_BYREF|VT_R8.
    VARIANT_BOOL FAR* pboolVal; // VT_BYREF|VT_BOOL.
    SCODE FAR* pscode; // VT_BYREF|VT_ERROR.
    CY FAR* pcyVal; // VT_BYREF|VT_CY.
    DATE FAR* pdate; // VT_BYREF|VT_DATE.
    BSTR FAR* pbstrVal; // VT_BYREF|VT_BSTR.
    IUnknown FAR* FAR* ppunkVal; // VT_BYREF|VT_UNKNOWN.
    IDispatch FAR* FAR* ppdispVal; // VT_BYREF|VT_DISPATCH.
    SAFEARRAY FAR* FAR* pparray; // VT_ARRAY|*.
    VARIANT FAR* pvarVal; // VT_BYREF|VT_VARIANT.
    void FAR* byref; // Generic ByRef.
    char cVal; // VT_I1.
    unsigned short uiVal; // VT_UI2.
    unsigned long ulVal; // VT_UI4.
    int intVal; // VT_INT.
    unsigned int uintVal; // VT_UINT.
    char FAR * pcVal; // VT_BYREF|VT_I1.
    unsigned short FAR * puiVal; // VT_BYREF|VT_UI2.
    unsigned long FAR * pulVal; // VT_BYREF|VT_UI4.
    int FAR * pintVal; // VT_BYREF|VT_INT.
    unsigned int FAR * puintVal; //VT_BYREF|VT_UINT.

  • _variant_t是VARIANT的封装类Q其赋值可以用强制类型{换,其构造函C自动处理q些数据cd?br>使用旉加上#include <comdef.h>
    例如Q?br>long l=222;
    ing i=100;
    _variant_t lVal(l);
    lVal = (long)i;

  • COleVariant的用与_variant_t的方法基本一P请参考如下例子:
    COleVariant v3 = "字符?, v4 = (long)1999;
    CString str =(BSTR)v3.pbstrVal;
    long i = v4.lVal;

六、其它一些COM数据cd

  • ҎProgID得到CLSID
    HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
    CLSID clsid;
    CLSIDFromProgID( L"MAPI.Folder",&clsid);
  • ҎCLSID得到ProgID
    WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
    例如我们已经定义?CLSID_IApplication,下面的代码得到ProgID
    LPOLESTR pProgID = 0;
    ProgIDFromCLSID( CLSID_IApplication,&pProgID);
    ...///可以使用pProgID
    CoTaskMemFree(pProgID);//不要忘记释放

七、ANSI与Unicode
UnicodeUCؓ宽字W型字串,COM里用的都是Unicode字符丌Ӏ?/p>

  • ANSI转换到Unicode
    (1)通过Lq个宏来实现Q例? CLSIDFromProgID( L"MAPI.Folder",&clsid);
    (2)通过MultiByteToWideChar函数实现转换,例如:
    char *szProgID = "MAPI.Folder";
    WCHAR szWideProgID[128];
    CLSID clsid;
    long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
    szWideProgID[lLen] = '\0';
    (3)通过A2W宏来实现,例如:
    USES_CONVERSION;
    CLSIDFromProgID( A2W(szProgID),&clsid);
  • Unicode转换到ANSI
    (1)使用WideCharToMultiByte,例如:
    // 假设已经有了一个Unicode ?wszSomeString...
    char szANSIString [MAX_PATH];
    WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );
    (2)使用W2A宏来实现,例如:
    USES_CONVERSION;
    pTemp=W2A(wszSomeString);

八、其?/strong>

  • Ҏ息的处理中我们经帔R要将WPARAM或LPARAM{?2位数据(DWORD)分解成两?6位数据(WORD),例如Q?br>LPARAM lParam;
    WORD loValue = LOWORD(lParam);///取低16?br>WORD hiValue = HIWORD(lParam);///取高16?br>
  • 对于16位的数据(WORD)我们可以用同LҎ分解成高低两?位数?BYTE),例如:
    WORD wValue;
    BYTE loValue = LOBYTE(wValue);///取低8?br>BYTE hiValue = HIBYTE(wValue);///取高8?br>
  • 两个16位数据(WORDQ合?2位数?DWORD,LRESULT,LPARAM,或WPARAM)
    LONG MAKELONG( WORD wLow, WORD wHigh );
    WPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
    LPARAM MAKELPARAM( WORD wLow, WORD wHigh );
    LRESULT MAKELRESULT( WORD wLow, WORD wHigh );

  • 两个8位的数据(BYTE)合成16位的数据(WORD)
    WORD MAKEWORD( BYTE bLow, BYTE bHigh );

  • 从R(red),G(green),B(blue)三色得到COLORREFcd的颜色?br>COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
    例如COLORREF bkcolor = RGB(0x22,0x98,0x34);

  • 从COLORREFcd的颜色值得到RGB三个颜色?br>BYTE Red = GetRValue(bkcolor); ///得到U颜?br>BYTE Green = GetGValue(bkcolor); ///得到lK?br>BYTE Blue = GetBValue(bkcolor); ///得到兰颜?br>

九、注意事?/strong>
假如需要用到ConvertBSTRToString此类函数,需要加上头文gcomutil.h,q在setting中加入comsupp.lib或者直接加?pragma comment( lib, "comsupp.lib" )



极品垃圾 2009-05-12 20:25 发表评论
]]>
关于BSTR数据cdhttp://www.shnenglu.com/bestcln/articles/82712.html极品垃圾极品垃圾Tue, 12 May 2009 09:44:00 GMThttp://www.shnenglu.com/bestcln/articles/82712.htmlhttp://www.shnenglu.com/bestcln/comments/82712.htmlhttp://www.shnenglu.com/bestcln/articles/82712.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/82712.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/82712.html字符串的长度可能互不相同Q因此跨COM边界传输特定的字W串Ӟ需要确定它的长度,而且Q字W串有时需?br>
分配内存?br>2.Unicode和ANSI数据cd
3.OLECHAR,LPOLESTR,LPCOLESTR
COM的基本字W数据类型是OLECHAR,与^台无关的字符表示法。在创徏该字W集ӞOLECHAR的基本数据类型随?br>
作系l的不同而不同。如今最行的COMq_是基于Win32_API的,而且Z此,OLECHAR是wchar_t的typedef. 

w表示它是Unicode字符。LPOLESTR是OLECHAR*的typedefQLPCOLESTR是同一U数据类型的const声明?br>4.处理LPOLESTR
如果你试囑ְ字符串DlLPOLESTRQ则会收到编译错误,例如Q?br>OLECHAR *olechar="A String!";//~译错误
反之Q你应在q样的字W串前添加L前缀Q如下所C:
LPOLESTR szMyString = L"This is a string!";
在用printf()或ATLTRACE()Ӟq尤光要(但通常被遗忘)
例如Q?br>LPOLESTR szstr = L"Hello!";
ATLTRACE("string=%s",szstr);
~译后打印的?br>string=T
昄是错误的Q应该添加L前缀或OLESTR()宏,应该如下写:
ATLTRACE(L"string=%s",szstr);
或?br>ATRTRACE(OLESTR("string=%s",szstr);
下面两个函数通常用来复制字符丌Ӏ第一个是ANSI函数wcscpy();
W二个是ATL函数Q名为ocscpy()
4.是否执行Unicode~译
实际上在默认情况下,ATL向导既创ZANSI配置Q又创徏了Unicode配置Q这使你能够一U格式或两种格式~译

及发布组件服务程序,你只需坚持使用TCHAR数据cdQ以便你的代码可以兼容两U字W集?br>5.TCHAR
TCHAR是一般的字符cd。TCHAR的定义如下:
#ifdef UNICODE
typedef WCHAR TCHAT
#else
typedef char TCHAR
#endif
默认情况下,C++字符串文字ؓchar*cdQ通过在字W串前用L前缀Q可以将他们指定为宽字符?br>在TCHAR*数据cdQ应该用_TQ例如:
TCHAR *p_tchar = _T("this is string";
此代码将字符串赋lANSI/UNICODE兼容格式的字W串。_T是个宏,ҎUNICODE来制定具体内宏V?br>6.使用BSTR处理不同大小的字W串?br>׃存在内存斚w的问题,因此使用BSTR数据cdQBSTR是指向OLECHAR字符串的指针Q可以利用字W串的长

度区分BSTRQ该长度不包括最后的nulll尾W,而且在字W串指针之前?个字节里指定。由于它是Unicode字符

Ԍ所以每个字W占?个字节,与LPOLESTRl尾方式一PBSTR也必Mnulll尾。BSTR避免了LPOLESTR的缺

P因ؓ它的长度是显C指定的Q所以null字符也可嵌入到BSTR中,所以BSTR可被用于发送二q制数据和简单字

W串。由于BSTRhҎl构Q因此增加了一些特D的API函数来处理BSTR.创徏和销毁BSTR时调用这些函数?br>(BSTR是LPOLESTR指针Qƈ且在指针的前面加?个字节来表示大小)
7.处理BSTR的常用API函数?br>应该使用SysAllocString()和SysFreeString()来管理BSTRcd
声明如下Q?br>BSTR SysAllocString(const OLECHAR *szSource);
反之Q用SysAllocStringLen()来指定结果BSTR的长度?br>所有的BSTR都必M用SysFreeString()释放。否则会造成内存泄漏?br>8.跨COM边界的字W串内存理?br>BSTR没有引用计数机制
Q?Q在传递字W串Ӟ服务器负责什么操作?br>COM服务器程序不应该l护跨COM边界传递的变量的引用,相反Q应该进行复制?br>在跨COM边界传递BSTRӞ服务器程序的理原则是客L序负责释放BSTR。无论BSTR是[in]q是[out]参数。都

如此。在字W串传递给客户E序Ӟ需要服务器E序释放该字W串的唯一时候是为[in,out]参数赋信g?br>
。此Ӟ客户E序传递被分配的字W串Q而服务器E序释放该字W串Q然后制订一个指针,他指向新分配的字W?br>
串的位置Q而且该字W串由客户E序释放Q对于服务器E序而言Q管理原则始l是创徏输入和输出BSTR的copy

Q而不是给现有BSTRd另一个引用?br>例如Q?br>STDMETHOD CstrigTest::GetValue(BSTR *pResult)
{
*pResult = m_str;
return S_OK;
}
//q是不对的,虽然没有 语法错误Q大q反了COM的管理规则,应该如下Q?br>Ҏ一Q?br>
STDMETHOD CstrigTest::GetValue(BSTR *pResult)
{
*pResult = SysAllocString(m_str);
return S_OK;
}
Ҏ二:
STDMETHOD CstrigTest::GetValue(BSTR *pResult)
{
*pResult = m_str;
m_str = NULL;
return S_OK;
}
输入参数时原则相同?br>下面是处理BSTR的指导方针:
Q?Q[in]参数必须由client拥有Q所以,如果服务器程序应该创建copyQ不应释放或更改q些参数?br>(2)[out]参数由client释放?br>Q?Q客L序必dNULL或释攄BSTR传递给服务器程序的[out]参数中?br>Q?Q在服务器程序在被赋予新的BSTRg前,[in,out]参数必须被释放?br>Q?Q始l用SysStringLen()获得BSTR的长度?br>COM+提供了两个类函数对字W串q行装:CComBSTR 和_bstr_t
9.字符串{换函?br>ATL字符串{换宏Q在使用M宏之前,一定要指定USER_CONVERSION宏,否则会遇到如下编译错误:error c2065:'_lpw'undeclared 

identifierQ?br>A2BSTR A2COLE A2CW .......(很多)
例如Q(使用W2A宏)
LPOLESTR szString=L"this is a string!";
char *str;
str = W2A(szString);
所有这些宏都是以ATL为基的,在ATL中用这些宏Ӟ目必须包括atlconv.h?br>COM+q定义了另外两个转换函数Q而且?import指o自动包含Q这两个函数都位于comutil.h文g中,q从属于_com_util名称I间Q他们可?br>
ANSI字符串{换成BSTRQ或者反向。函CؓQ?br>ConvertStringToBSTR()
ConvertBSTRToString()
10.CComBSTR(CComBSTR装了BSTR)
如果在BSTR出了其作用域时没有调用SysFreeString()Q则pȝ调用会造成内存泄漏?br>CComBSTR在ATL的atlbase.h头文件中定义Q因为它在一个ATL文g中定义,所以CComBSTR在ATL目中最常用Q以从COM客户E序中来回传递字W?br>
丌Ӏ?br>CComBSTR只有一个数据成员,名ؓm_str的公共BSTR。CComBSTR的用途是装BSTR数据cdQ以帮助BSTR的内存管理。还有ToUpper(),ToLower(

){将字符串{换ؓ特定的大写格式?br>Q在构造函数种分配内存Q在析构函数中释攑ֆ存)?br>在赋|实例化,删除时内存管理非常关键?br>Attach()转移所有权?br>必须是m_str=NULL时才能用Attach()
Detach()用于释放所有权Q?br>BSTR Detach()
{
BSTR s = m_str;
m_str = NULL;
return s;
}
Copy()函数用于复制字符丌Ӏ?br>11._bstr_t
_bstr_t保持内部的引用计?br>_bstr_t是由#import指o自动d的。与CComBSTR的最大区别是保持了一个内部引用。另一个区别是_bstr_t要求异常处理QATL目不会包括

异常处理Q因此_bstr_t更适合于COM客户E序Q_bstr_t的定义与实现位于comutil.h中?br>一个通用的原则是Q_bstr_tcd用于COM客户E序Q而CComBSTR应用于ATL服务器程序?br>12.其它数据cd
1.COM数据cd
COM name                   C++             size
Byte                      BYTE              8
Boolean                  VARIANT_BOOL       16
Double                   double              64
Float                     float             32
Integer                   int                  
Long                       long            32
Short                     short            16
String                     BSTR
Date                       DATE
Variant                    VARIANT           
Dispatch Interface          IDispatch*
Unknown Interface           IUnknown*
2.VARIANTl构
3._variant_t
_variant_t是micsoftҎ的,它是VARIANT的C++装器类
4.传递数l?br>传递数l的cd为:SAFEARRAY**?br>

极品垃圾 2009-05-12 17:44 发表评论
]]>
_variant_t 是什么数据类型?Q?/title><link>http://www.shnenglu.com/bestcln/articles/82711.html</link><dc:creator>极品垃圾</dc:creator><author>极品垃圾</author><pubDate>Tue, 12 May 2009 09:43:00 GMT</pubDate><guid>http://www.shnenglu.com/bestcln/articles/82711.html</guid><wfw:comment>http://www.shnenglu.com/bestcln/comments/82711.html</wfw:comment><comments>http://www.shnenglu.com/bestcln/articles/82711.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/bestcln/comments/commentRss/82711.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/bestcln/services/trackbacks/82711.html</trackback:ping><description><![CDATA[q个问题的答案比较广泛:   <br>  我所知道常用?  <br>  1。在执行的SQL语句一般都是_bstr_t   <br>  2.Connection   中的RecordsAffected   为VARIANT   <br>  3.使用get_Value()获得的记录的gؓ   VAARIANT   <br>      {等。。?  <br>  _bstr_t   中记录了字符串的长度Q?  <br>  _variant_t   记录有数据的cd和数据的?  <br>      ?  _variant_t   ttt;   <br>      ttt.vt=I4_VT;   表示数据cd为整?  <br>      ttt.lVal   为数据的? <img src ="http://www.shnenglu.com/bestcln/aggbug/82711.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/bestcln/" target="_blank">极品垃圾</a> 2009-05-12 17:43 <a href="http://www.shnenglu.com/bestcln/articles/82711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc定义全局变量http://www.shnenglu.com/bestcln/articles/82658.html极品垃圾极品垃圾Tue, 12 May 2009 01:53:00 GMThttp://www.shnenglu.com/bestcln/articles/82658.htmlhttp://www.shnenglu.com/bestcln/comments/82658.htmlhttp://www.shnenglu.com/bestcln/articles/82658.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/82658.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/82658.html全局变量一般这样定义:
1。在一cȝ.cpp中定?int myInt;
然后再在要用到的地方?cpp里extern int myIntQ这样就可以用了?/font>

2。在stdafx.cpp中加?
int myInt;
然后在stdafx.h中加?
extern int myInt
q样定义以后无论在什么文件中都是可见?

3。比较规范的是,先定义一个Glbs.hQ把所有的全局变量原始定义放进厅R然后定义一个Externs.hQ把你先前定义在Glbs.h中的变量都加上extern。注意:如果你在Glbs.h中设|了初|那么在Externs.h中就不要加g。然后调用时Q第一ơ调用的Qi nclude <Glbs.h>Q以后调用的Qi nclude <Externs.h>

另:

问:如何在VC++中用全局变量Q以使文档中的所有类都能讉K?br>  {:把该变量攑ֈ该应用程序类的头文g中的attribute处。然后,在程序的M地方Q你都可以用下面的方法来讉K该变量:
  CMyApp *app=QCMyApp*QAfxGet-AppQ)Q?br>  app->MyGlobalVariable=…
  用这个方法,不但可以定义全局变量Q也可以定义全局对象?br>  例如Q?br>  MyClass MyObjectQ?br>  CMyApp*app=QCMyApp*QAfxGet-AppQ)Q?br>  app->MyObject.MyFunctionQ)Q?/font>

 

VC中用全局变量?U办法及防错措施

  
  1. 对于全局变量存在和函CL问题Qؓ了在其他CPP文g中能够访问这些变量,必须在主文g的H文g中加上extern声明Q格式如下:
extern varibletype var; Q声明)
在主文g的CPP文g中定?br>varibletype var; Q定义)
例子:
AppWizard建立一个Test工程
那么在Test.h中声明extern CString cs;
在Test.app定义CString cs;

   如果要定义整个工E的全局变量Q在M一个CPP文g中进行定义,然后在需要引用这个变量的文g中进行声明。如全局变量很多可以选择使用定义全局变量的。h文gQ在需要的地方直接include头文件即可,不需要写那么多extern了?br>2.应用E序cȝd文g处定义变量varibletype varQ然后,在程序的M地方Q都可以用下面的Ҏ来访问该变量Q?nbsp;
  CClassApp *app=(CClassApp*)AfxGetApp(); 
  app->var=
 cM的,以上Ҏ也可以定义全局对象
例子:
AppWizard建立一个Test工程
那么在Test.h中声?CString cs;
使用的时候CTestApp *app=(CTestApp*)AfxGetApp(); 
    app->cs="Global"
 
防错措施Q?br>若定义的函数和全局变量在多个文件包含且造成嵌套或多ơ调用的话,q样导致这个头文g每被包含依次Q函数或变量p重新定义一ơ,在链接编译时会导致重定义错误。ؓ此需要用一U被UCؓGuard macro的技术来保证不出错。在一个头文g开头加?nbsp;
#ifndef   _MACRO_1_
#define   _MACRO_1_
在文件末֢?nbsp;
#endif



极品垃圾 2009-05-12 09:53 发表评论
]]>
VC 串口调试http://www.shnenglu.com/bestcln/articles/80270.html极品垃圾极品垃圾Fri, 17 Apr 2009 09:29:00 GMThttp://www.shnenglu.com/bestcln/articles/80270.htmlhttp://www.shnenglu.com/bestcln/comments/80270.htmlhttp://www.shnenglu.com/bestcln/articles/80270.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/80270.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/80270.html1.建立目Q?/span>

打开VCQ+6.0Q徏立一个基于对话框的MFC应用E序SCommTest;

2.在项目中插入MSComm控g  

选择Project菜单下Add To Project子菜单中?Components and Controls…选项Q在弹出的对话框中双击Registered ActiveX Controls(E等一会,q个q程较慢Q,则所有注册过的ActiveX控g出现在列表框中?选择Microsoft Communications Control, version 6.0Q,单击Insert按钮它插入到我们的Project中来Q接受缺省的选项。(如果你在控g列表中看不到Microsoft Communications Control, version 6.0Q那可能是你在安装VC6时没有把ActiveX一w上Q重新安装VC6Q选上ActiveX可以了Q,

q时在ClassView视窗中就可以看到CMSCommcMQ(注意Q此cdClassWizard中看不到Q重构clw文g也一PQƈ且在控g工具栏Controls中出C电话图标Q如?所C)Q现在要做的是用鼠标此图标拖到对话框中Q程序运行后Q这个图标是看不到的?/span>

3.利用ClassWizard定义CMSCommcL制对?/span>

打开ClassWizardQ?gt;Member Viariables选项卡,选择CSCommTestDlgc,为IDC_MSCOMM1d控制变量Qm_ctrlCommQ这时你可以看一看,在对话框头文件中自动加入?/{{AFX_INCLUDES() Qi nclude "mscomm.h" //}}AFX_INCLUDES ?/span>

4.在对话框中添加控?/span>
 
向主对话框中d两个~辑框,一个用于接收显C数据ID为IDC_EDIT_RXDATAQ另一个用于输入发送数据,ID为IDC_EDIT_TXDATAQ再d一个按钮,功能是按一ơ就把发送编辑框中的内容发送一ơ,其ID设ؓIDC_BUTTON_MANUALSEND。别忘记了将接收~辑框的PropertiesQ?gt;Styles中把Miltiline和Vertical Scroll属性选上Q发送编辑框若你惌入多行文字,也可选上Miltiline?/span>

再打开ClassWizardQ?gt;Member Viariables选项卡,选择CSCommTestDlgc, 为IDC_EDIT_RXDATAdCString变量m_strRXDataQ?为IDC_EDIT_TXDATAdCString变量m_strTXData。说明: m_strRXData和m_strTXData分别用来攑օ接收和发送的字符数据?/span>

5.d串口事g消息处理函数OnComm()

打开ClassWizardQ?gt;Message MapsQ选择cCSCommTestDlgQ选择IDC_MSCOMM1Q双L息OnCommQ将弹出的对话框中将函数名改为OnComm?/span>

q个函数是用来处理串口消息事件的Q如每当串口接收到数据,׃产生一个串口接收数据缓冲区中有字符的消息事Ӟ我们刚才d的函数就会执行,我们在OnComm()函数加入相应的处理代码就能实现自已想要的功能了。请你在函数中加入如下代码:

void CSCommTestDlg::OnComm()
{
    // TODO: Add your control notification handler code here
    VARIANT variant_inp;
    COleSafeArray safearray_inp;
    LONG len,k;
    BYTE rxdata[2048]; //讄BYTE数组 An 8-bit integerthat is not signed.
    CString strtemp;
    if(m_ctrlComm.GetCommEvent()==2) //事ggؓ2表示接收~冲区内有字W?br>    {             ////////以下你可以根据自q通信协议加入处理代码
        variant_inp=m_ctrlComm.GetInput(); //ȝ冲区
        safearray_inp=variant_inp; //VARIANT型变量{换ؓColeSafeArray型变?br>        len="safearray"_inp.GetOneDimSize(); //得到有效数据长度
        for(k=0;k<len;k++)
            safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数l?br>        for(k=0;k<len;k++) //数l{换ؓCstring型变?br>        {
            BYTE bt=*(char*)(rxdata+k); //字符?br>            strtemp.Format("%c",bt); //字W送入临时变量strtemp存放
            m_strRXData+=strtemp; //加入接收~辑框对应字W串
        }
    }
    UpdateData(FALSE); //更新~辑框内?br>
}

到目前ؓ止还不能在接收编辑框中看到数据,因ؓ我们q没有打开串口Q但q行E序不应该有M错误Q不Ӟ你肯定哪儿没看仔l,因ؓ我是打开VC6对照着做一步写一行的Q运行试试。没错吧Q那么做下一步:

6.打开串口和设|串口参?/span>

你可以在你需要的时候打开串口Q例如在E序中做一个开始按钮,在该按钮的处理函C打开串口。现在我们在d话框的CSCommTestDlg::OnInitDialog()打开串口Q加入如下代码:

// TODO: Add extra initialization here
if(m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(FALSE);

m_ctrlComm.SetCommPort(1); //选择com1
if( !m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE);//打开串口
else
AfxMessageBox("cannot open serial port");

m_ctrlComm.SetSettings("9600,n,8,1"); //波特?600Q无校验Q?个数据位Q?个停止位

m_ctrlComm.SetInputModel(1); //1Q表CZ二进制方式检取数?br>m_ctrlComm.SetRThreshold(1);
//参数1表示每当串口接收~冲Z有多于或{于1个字W时引发一个接收数据的OnComm事g
m_ctrlComm.SetInputLen(0); //讄当前接收区数据长度ؓ0
m_ctrlComm.GetInput();//先预ȝ冲区以清除残留数?/span>

现在你可以试试程序了Q将串口U接好后Q?span style="FONT-SIZE: 12pt; COLOR: #999999">不会接?ȝ看我写的串口接线基本ҎQ,打开串口调试助手Qƈ串口设在com2Q选上自动发送,也可以等会手动发送。再执行你编写的E序Q接收框里应该有数据昄了?/span>

7.发送数?/span>

先ؓ发送按钮添加一个单L息即BN_CLICKED处理函数Q打开ClassWizardQ?gt;Message MapsQ选择cCSCommTestDlgQ选择IDC_BUTTON_MANUALSENDQ双击BN_CLICKEDdOnButtonManualsend()函数Qƈ在函Cd如下代码Q?/span>

void CSCommTestDlg::OnButtonManualsend()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //d~辑框内?br>m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送数?br>}

q行E序Q在发送编辑框中随意输入点什么,单击发送按钮,啊!看看Q在另一端的串口调试助手Q或别的调试工具Q接收框里出C什么?/span>

如果你真是初ơ涉猎串口编E,又一ơ成功,那该说声谢谢我了Q因为我W一ơ做串口E序时可费劲了,那时|上的资料也不好找。开开玩笑Q谢谢你的支持,有什么好东西别忘了给我寄一份?/span>

说明Q?/span>

׃用到VC控gQ在没有安装VC的计机上运行时要从VC中把mscomm32.ocx、msvcrt.dll、mfc42.dll拷到Windows目录下的System子目录中Qwin2000为System32Qƈ再进行注册设|?/span>



极品垃圾 2009-04-17 17:29 发表评论
]]>
使用标准C++的类型{换符Qstatic_cast、dynamic_cast、reinterpret_cast、和const_cast??http://www.shnenglu.com/bestcln/articles/76572.html极品垃圾极品垃圾Sat, 14 Mar 2009 05:20:00 GMThttp://www.shnenglu.com/bestcln/articles/76572.htmlhttp://www.shnenglu.com/bestcln/comments/76572.htmlhttp://www.shnenglu.com/bestcln/articles/76572.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/76572.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/76572.html使用标准C++的类型{换符Qstatic_cast、dynamic_cast、reinterpret_cast、和const_cast?/font>

3.1 static_cast
用法Qstatic_cast < type-id > ( expression )     
该运符把expression转换为type-idcdQ但没有q行时类型检查来保证转换的安全性。它主要有如下几U用法:
①用于类层次l构中基cd子类之间指针或引用的转换?br>  q行上行转换Q把子类的指针或引用转换成基c表C)是安全的Q?br>  q行下行转换Q把基类指针或引用{换成子类表示Q时Q由于没有动态类型检查,所以是不安全的?br>②用于基本数据类型之间的转换Q如把int转换成charQ把int转换成enum。这U{换的安全性也要开发h员来保证?br>③把I指针{换成目标cd的空指针?br>④把Mcd的表辑ּ转换成voidcd?/font>

注意Qstatic_cast不能转换掉expression的const、volitale、或者__unaligned属性?/font>


3.2 dynamic_cast
用法Qdynamic_cast < type-id > ( expression )
该运符把expression转换成type-idcd的对象。Type-id必须是类的指针、类的引用或者void *Q?br>如果type-id是类指针cdQ那么expression也必L一个指针,如果type-id是一个引用,那么expression也必L一个引用?/font>

dynamic_cast主要用于cdơ间的上行{换和下行转换Q还可以用于cM间的交叉转换?br>在类层次间进行上行{换时Qdynamic_cast和static_cast的效果是一LQ?br>在进行下行{换时Qdynamic_casthcd查的功能Q比static_cast更安全?br>class B{
public:
       int m_iNum;
       virtual void foo();
};

class D:public B{
    public:
       char *m_szName[100];
};

void func(B *pb){
    D *pd1 = static_cast<D *>(pb);
    D *pd2 = dynamic_cast<D *>(pb);
}

在上面的代码D中Q如果pb指向一个Dcd的对象,pd1和pd2是一LQƈ且对q两个指针执行Dcd的Q何操作都是安全的Q?br>但是Q如果pb指向的是一个Bcd的对象,那么pd1是一个指向该对象的指针,对它q行Dcd的操作将是不安全的(如访问m_szNameQ,
而pd2是一个空指针?/font>

另外要注意:B要有虚函敎ͼ否则会编译出错;static_cast则没有这个限制?br>q是׃q行时类型检查需要运行时cd信息Q而这个信息存储在cȝ虚函数表Q?br>关于虚函数表的概念,详细可见<Inside c++ object model>Q中Q只有定义了虚函数的cL有虚函数表,
没有定义虚函数的cL没有虚函数表的?/font>

另外Qdynamic_castq支持交叉{换(cross castQ。如下代码所C?br>class A{
public:
        int m_iNum;
        virtual void f(){}
};

class B:public A{
};

class D:public A{
};

void foo(){
    B *pb = new B;
    pb->m_iNum = 100;

    D *pd1 = static_cast<D *>(pb);    //compile error
    D *pd2 = dynamic_cast<D *>(pb);  //pd2 is NULL
    delete pb;
}

在函数foo中,使用static_castq行转换是不被允许的Q将在编译时出错Q而?dynamic_cast的{换则是允许的Q结果是I指针?/font>


3.3 reinpreter_cast
用法Qreinpreter_cast<type-id> (expression)
type-id必须是一个指针、引用、算术类型、函数指针或者成员指针?br>它可以把一个指针{换成一个整敎ͼ也可以把一个整数{换成一个指针(先把一个指针{换成一个整敎ͼ
在把该整数{换成原类型的指针Q还可以得到原先的指针|?/font>

该运符的用法比较多?/font>

3.4 const_cast
用法Qconst_cast<type_id> (expression)
该运符用来修改cd的const或volatile属性。除了const 或volatile修饰之外Q?type_id和expression的类型是一L?br>帔R指针被{化成非常量指针,q且仍然指向原来的对象;
帔R引用被{换成非常量引用,q且仍然指向原来的对象;帔R对象被{换成非常量对象?/font>

Voiatile和constc试。D如下一例:
class B{
public:
     int m_iNum;
}
void foo(){
 const B b1;
 b1.m_iNum = 100;            //comile error
 B b2 = const_cast<B>(b1);
 b2. m_iNum = 200;           //fine
}
上面的代码编译时会报错,因ؓb1是一个常量对象,不能对它q行改变Q?br>使用const_cast把它转换成一个常量对象,可以对它的数据成员L改变。注意:b1和b2是两个不同的对象?br>



极品垃圾 2009-03-14 13:20 发表评论
]]>
VC++的工E文件说明:http://www.shnenglu.com/bestcln/articles/66767.html极品垃圾极品垃圾Wed, 12 Nov 2008 14:18:00 GMThttp://www.shnenglu.com/bestcln/articles/66767.htmlhttp://www.shnenglu.com/bestcln/comments/66767.htmlhttp://www.shnenglu.com/bestcln/articles/66767.html#Feedback0http://www.shnenglu.com/bestcln/comments/commentRss/66767.htmlhttp://www.shnenglu.com/bestcln/services/trackbacks/66767.htmlVC++的工E文件说明:

VC目文g说明
.dsp   (developer studio project) 是VC++的项目文?文本格式。项目参数配|文Ӟq个文g太重要,重点保护对象?nbsp;   
.dsw (developer studio worksapce )工作区文Ӟ重要性一般,因ؓ它信息不我,Ҏ恢复。它可以指向一个或多个.dsp文g
.cQ源代码文gQ按C语言用法~译处理?br>.cppQ源代码文gQ按C++语法~译处理?br>.rcQ资源文件?br>      
以下文g在项目中是可丢弃的,有些文g删除后,VC会自动生成的?br>.clw ClassWizard信息文g,实际上是INI文g的格?有兴可以研I一?有时候ClassWizard出问?手工修改CLW文g可以解决.如果此文件不存在的话,每次用ClassWizard的时候绘提示你是否重?
.ncb 无编译浏览文?no compile browser)。当自动完成功能出问题时可以删除此文件。build后会自动生成?br>.opt 工程关于开发环境的参数文g。如工具条位|等信息Q?可丢?     
.aps (AppStudio File),资源辅助文g,二进制格?一般不用去他.
.plg 是编译信息文?~译时的error和warning信息文gQ实际上是一个html文gQ?一般用处不?在Tools->Options里面有个选项可以控制q个文g的生? (建立日志文g)
.hpj (Help Project)是生成帮助文件的工程,用microsfot Help Compiler可以处理.
.mdp (Microsoft DevStudio Project)是旧版本的项目文?如果要打开此文件的?会提CZ是否转换成新的DSP格式.
.bsc 是用于浏览项目信息的,如果用Source Brower的话必Lq个文g.如果不用q个功能的话,可以在Project Options里面LGenerate Browse Info File,可以加快~译速度.
.map 是执行文件的映像信息U录文g,除非对系l底层非常熟?q个文g一般用不着.
.pch (Pre-Compiled File)是预~译文g,可以加快~译速度,但是文g非常?
.pdb (Program Database)记录了程序有关的一些数据和调试信息,在调试的时候可能有?
.exp 只有在编译DLL的时候才会生?记录了DLL文g中的一些信?一般也没什么用. 



极品垃圾 2008-11-12 22:18 发表评论
]]>
þþƷˬ97 | ȫþվ| ޼VëƬþþƷ| 69Ʒþþþùۿ| Ļþ| re99þþƷ99| þùƷ-Ʒ| þþƷ99þ˿| þþùƵ| Ʒþ޲| þѹۿƵ| ޾ƷŮþþþ99| 99þþƷѾƷ| ޹ƷۺϾþ| þùƷ99Ʒ987| ȾþùþƷ| ˮϵþþƷ| þ޾Ʒ벥| aaaƷþþùƬ| ɫۺϺϾþۿ| þþƷоƷ| AV12þ | ھƷþۺ88| þþavҰһ| þۺϾɫۺϾ99| 97rþþƷ99| þAV뾫Ʒɫҹ鶹 | þþƷ| Ʒxxxxˮ޹Ʒþһ | 99ξþþŷƷվ| þþžžþƷֱ| þ99ۺϾƷŮͬ| þþþþۺ| ճˮþ޾Ʒtv| Ʒþþþþù| VVþþ| þþŮһ| þݺҹҹ2O2O| þۺϾþڹ| ˾þô߽AVɫɫ| ŷ޾þþþƷ|