??xml version="1.0" encoding="utf-8" standalone="yes"?>麻豆国内精品久久久久久,亚洲国产美女精品久久久久∴,久久丫忘忧草产品http://www.shnenglu.com/lhking/czh-cnWed, 07 May 2025 06:50:55 GMTWed, 07 May 2025 06:50:55 GMT60Using memset(), memcpy(), and memmove() in Chttp://www.shnenglu.com/lhking/archive/2010/08/31/125375.htmllhkinglhkingTue, 31 Aug 2010 03:06:00 GMThttp://www.shnenglu.com/lhking/archive/2010/08/31/125375.htmlhttp://www.shnenglu.com/lhking/comments/125375.htmlhttp://www.shnenglu.com/lhking/archive/2010/08/31/125375.html#Feedback0http://www.shnenglu.com/lhking/comments/commentRss/125375.htmlhttp://www.shnenglu.com/lhking/services/trackbacks/125375.htmlThe article is from http://www.java-samples.com/showtutorial.php?tutorialid=591

To set all the bytes in a block of memory to a particular value, use memset(). The function prototype is

void * memset(void *dest, int c, size_t count);

The argument dest points to the block of memory. c is the value to set, and count is the number of bytes, starting at dest, to be set. Note that while c is a type int, it is treated as a type char. In other words, only the low-order byte is used, and you can specify values of c only in the range 0 through 255.

Use memset() to initialize a block of memory to a specified value. Because this function can use only a type char as the initialization value, it is not useful for working with blocks of data types other than type char, except when you want to initialize to 0. In other words, it wouldn't be efficient to use memset() to initialize an array of type int to the value 99, but you could initialize all array elements to the value 0. memset() will be demonstrated in program below.

The memcpy() Function

memcpy() copies bytes of data between memory blocks, sometimes called buffers. This function doesn't care about the type of data being copied--it simply makes an exact byte-for-byte copy. The function prototype is

void *memcpy(void *dest, void *src, size_t count);

The arguments dest and src point to the destination and source memory blocks, respectively. count specifies the number of bytes to be copied. The return value is dest. If the two blocks of memory overlap, the function might not operate properly--some of the data in src might be overwritten before being copied. Use the memmove() function, discussed next, to handle overlapping memory blocks. memcpy() will be demonstrated in program below.

The memmove() Function

memmove() is very much like memcpy(), copying a specified number of bytes from one memory block to another. It's more flexible, however, because it can handle overlapping memory blocks properly. Because memmove() can do everything memcpy() can do with the added flexibility of dealing with overlapping blocks, you rarely, if ever, should have a reason to use memcpy(). The prototype is

void *memmove(void *dest, void *src, size_t count);

dest and src point to the destination and source memory blocks, and count specifies the number of bytes to be copied. The return value is dest. If the blocks overlap, this function ensures that the source data in the overlapped region is copied before being overwritten. Sample program below demonstrates memset(), memcpy(), and memmove().

A demonstration of memset(), memcpy(), and memmove().

1: /* Demonstrating memset(), memcpy(), and memmove(). */
2:
3: #include <stdio.h>
4: #include <string.h>
4:
5: char message1[60] = "Four score and seven years ago ...";
6: char message2[60] = "abcdefghijklmnopqrstuvwxyz";
7: char temp[60];
8:
9: main()
10: {
11:    printf("\nmessage1[] before memset():\t%s", message1);
12:    memset(message1 + 5, `@', 10);
13:    printf("\nmessage1[] after memset():\t%s", message1);
14:
15:    strcpy(temp, message2);
16:    printf("\n\nOriginal message: %s", temp);
17:    memcpy(temp + 4, temp + 16, 10);
18:    printf("\nAfter memcpy() without overlap:\t%s", temp);
19:    strcpy(temp, message2);
20:    memcpy(temp + 6, temp + 4, 10);
21:    printf("\nAfter memcpy() with overlap:\t%s", temp);
22:
23:    strcpy(temp, message2);
24:    printf("\n\nOriginal message: %s", temp);
25:    memmove(temp + 4, temp + 16, 10);
26:    printf("\nAfter memmove() without overlap:\t%s", temp);
27:    strcpy(temp, message2);
28:    memmove(temp + 6, temp + 4, 10);
29:    printf("\nAfter memmove() with overlap:\t%s\n", temp);
30:
31: }
message1[] before memset():     Four score and seven years ago ...
message1[] after memset():      Four @@@@@@@@@@seven years ago ...
Original message: abcdefghijklmnopqrstuvwxyz
After memcpy() without overlap: abcdqrstuvwxyzopqrstuvwxyz
After memcpy() with overlap:    abcdefefefefefefqrstuvwxyz
Original message: abcdefghijklmnopqrstuvwxyz
After memmove() without overlap:        abcdqrstuvwxyzopqrstuvwxyz
After memmove() with overlap:   abcdefefghijklmnqrstuvwxyz

ANALYSIS: The operation of memset() is straightforward. Note how the pointer notation message1 + 5 is used to specify that memset() is to start setting characters at the sixth character in message1[] (remember, arrays are zero-based). As a result, the 6th through 15th characters in message1[] have been changed to @.

When source and destination do not overlap, memcpy() works fine. The 10 characters of temp[] starting at position 17 (the letters q through z) have been copied to positions 5 though 14, where the letters e though n were originally located. If, however, the source and destination overlap, things are different. When the function tries to copy 10 characters starting at position 4 to position 6, an overlap of 8 positions occurs. You might expect the letters e through n to be copied over the letters g through p. Instead, the letters e and f are repeated five times.

If there's no overlap, memmove() works just like memcpy(). With overlap, however, memmove() copies the original source characters to the destination.



lhking 2010-08-31 11:06 发表评论
]]>
Vc++6.0目q到vs2005 应该注意的问?/title><link>http://www.shnenglu.com/lhking/archive/2010/06/26/118751.html</link><dc:creator>lhking</dc:creator><author>lhking</author><pubDate>Sat, 26 Jun 2010 01:22:00 GMT</pubDate><guid>http://www.shnenglu.com/lhking/archive/2010/06/26/118751.html</guid><wfw:comment>http://www.shnenglu.com/lhking/comments/118751.html</wfw:comment><comments>http://www.shnenglu.com/lhking/archive/2010/06/26/118751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/lhking/comments/commentRss/118751.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lhking/services/trackbacks/118751.html</trackback:ping><description><![CDATA[<p>Vc++6.0目q到vs2005 应该注意的问?br><a >www.firnow.com</a>    旉 Q?2010-06-06  作者:佚名   ~辑Q壹枝雪p?点击Q?nbsp; 1176 [ 评论 ]<br>-<br>-<br>l合 资源 电子?C֌   1.如果MessageBox("aa") 报错Q将其要Ҏ MessageBox(_TEXT("aa")).我喜Ƣ用MessageBox来调试程序,其是在写脚本时Q当你不知道E序有没有执行该条语句,以及执行完该条语句后某个变量的值发生了什么变化,在该条语句前后各加一个MessageBoxQstrQ,一目了然了?.</p> <p>2.pow(2,10)   要改?nbsp; pow((double)2,10)或pow(2.0,10)</p> <p>       说明Q?.0中用到math.h pow()函數時,有這個原?double pow(int _X,int _Y) 但如果用VC++ 2005的話Qpow()的第一個參數就不能再用int型態Q只能用float、double、long doubleQVC++ 2005在編譯時會做type checkingQ然後就過不了,报error C2668</p> <p>3.ItoaҎ名要Ҏ  _Itoa_s</p> <p>4.error C2440Q?#8220;static_cast” 无法?#8220;void (__thiscall CChatManagerDlg::* )(WPARAM,LPARAM)”转换?#8220;LRESULT (__thiscall CWnd::* )Q出错处在ON_MESSAGE(WM_SETPLAY,OnSetPlay)</p> <p>解答Q将void CVideoBaseView::OnSetPlay(WPARAM wp,LPARAM lp)  ҎLRESULT CVideoBaseView::OnSetPlay(WPARAM wp,LPARAM lp){</p> <p>LRESULT result = Default(); </p> <p>//你原来的代码</p> <p>return result;}</p> <p>5.找不到MFC80D.DLL</p> <p>解决Q?#8220;工程属?#8221;->“link”->“manifesto file”->“$(IntDir)\$(TargetFileName).intermediate.manifest” ?nbsp;    Ҏ    $(IntDir)\$(TargetFileName).manifest</p> <p>文章出处Q飞诺网(<a >www.firnow.com):http://dev.firnow.com/course/3_program/vc/vc_js/200879/132413.html</a></p> <img src ="http://www.shnenglu.com/lhking/aggbug/118751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lhking/" target="_blank">lhking</a> 2010-06-26 09:22 <a href="http://www.shnenglu.com/lhking/archive/2010/06/26/118751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>win32 vc Lxhttp://www.shnenglu.com/lhking/archive/2010/06/24/118613.htmllhkinglhkingThu, 24 Jun 2010 03:03:00 GMThttp://www.shnenglu.com/lhking/archive/2010/06/24/118613.htmlhttp://www.shnenglu.com/lhking/comments/118613.htmlhttp://www.shnenglu.com/lhking/archive/2010/06/24/118613.html#Feedback1http://www.shnenglu.com/lhking/comments/commentRss/118613.htmlhttp://www.shnenglu.com/lhking/services/trackbacks/118613.htmlҎMSDN的描qͼ采用如下的代码来实现LxQ结果发现在有的机器上能够阻止关机,在有的机器上却不能阻?虽然能看到弹出的MessageBoxQ但q来不及反应Q马上就x??都是WinXP SP2的机?

view plaincopy to clipboardprint?
LRESULT CPreventShutdownDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)  
{  
    if (WM_QUERYENDSESSION == message)  
    {  
        AfxMessageBox(_T("呵呵Q不许关机!"));  
        return FALSE;  // ҎMSDNQWM_QUERYENDSESSION q回FALSE则取消关?nbsp; 
    }  
 
    return CDialog::WindowProc(message, wParam, lParam);  

LRESULT CPreventShutdownDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    if (WM_QUERYENDSESSION == message)
    {
        AfxMessageBox(_T("呵呵Q不许关机!"));
        return FALSE;  // ҎMSDNQWM_QUERYENDSESSION q回FALSE则取消关?br>    }

    return CDialog::WindowProc(message, wParam, lParam);
}

是什么原因在某些机器上无法阻止关机呢Q?/p>

回忆x时经帔R到的场景Q?/p>

1. 如果某个q程失去响应Q关机的时候会提示"...没有响应Q是否结?

2. 使用C本修改了文Q在没有保存的情况下q行xQ普通情况会提示是否q行保存?/p>

1q种情况不好模拟Q但?是很好模拟的。于是在不能Lx的机器上q样q行试Q发现虽然也弹出了是否保存的对话框,但是q是马上关Z?/p>

果然Q和E序无关Q应该是机器讄的问题。于是想C一个很行的词Q?快速关?

到网上google了一下,发现快速关机是通过如下的方式实现的Q?/p>

HKEY-CURRENT-USER\Control Panel\Desktop\AutoEndTasks  gؓ1表示快速关?/p>

                                                                                        普通情况gؓ0或这个键g存在

C能阻止快速关机的机器上一看,果然q个键gؓ1.

改ؓ0后再q行E序Q就都能Lx了?/p>

【结论】阻止关机需要两步才能完的实现Q而不仅仅是MSDN中描q的2)

            1) 在程序中先删除这个键?HKEY-CURRENT-USER\Control Panel\Desktop\AutoEndTasks)

            2) 处理 WM_QUERYENDSESSION 时返回FALSE

 

本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/skyxie/archive/2009/06/09/4255767.aspx



lhking 2010-06-24 11:03 发表评论
]]>
C++调试技?/title><link>http://www.shnenglu.com/lhking/archive/2010/06/23/118591.html</link><dc:creator>lhking</dc:creator><author>lhking</author><pubDate>Wed, 23 Jun 2010 15:14:00 GMT</pubDate><guid>http://www.shnenglu.com/lhking/archive/2010/06/23/118591.html</guid><wfw:comment>http://www.shnenglu.com/lhking/comments/118591.html</wfw:comment><comments>http://www.shnenglu.com/lhking/archive/2010/06/23/118591.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/lhking/comments/commentRss/118591.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/lhking/services/trackbacks/118591.html</trackback:ping><description><![CDATA[<font color=#008080>查看未被delete掉的内存Q在输出H口中查?br>1</font> <span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> _CRTDBG_MAP_ALLOC</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">stdlib.h</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">crtdbg.h</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> wmain(vint argc , wchar_t</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> args[])<br></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">{<br></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> q里q行E序Qƈ在下面的函数调用之前delete掉所有new的东?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    _CrtDumpMemoryLeaks();<br></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">}</span> <img src ="http://www.shnenglu.com/lhking/aggbug/118591.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/lhking/" target="_blank">lhking</a> 2010-06-23 23:14 <a href="http://www.shnenglu.com/lhking/archive/2010/06/23/118591.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Zc++q程注入的实?http://www.shnenglu.com/lhking/archive/2010/06/23/118571.htmllhkinglhkingWed, 23 Jun 2010 07:33:00 GMThttp://www.shnenglu.com/lhking/archive/2010/06/23/118571.htmlhttp://www.shnenglu.com/lhking/comments/118571.htmlhttp://www.shnenglu.com/lhking/archive/2010/06/23/118571.html#Feedback0http://www.shnenglu.com/lhking/comments/commentRss/118571.htmlhttp://www.shnenglu.com/lhking/services/trackbacks/118571.html要实现对一个程序的q程注入Q然后对被注入的q程q行控制Q首先需要查扑ֈ要注入的q程ID。如何获取的q程ID呢?windows提供了一个API只要知道了这个进E里面的一个窗口句柄,可以找到找到该q程ID。函数Ş式如下:DWORD GetWindowThreadProcessId(
  HWND hWnd,
  LPDWORD lpdwProcessId
);

那如何获取这个窗口的句柄呢?很自然我们可以想到这么一个函敎ͼ函数形式如下Q?/p>

HWND FindWindowEx(     
    HWND hwndParent,
    HWND hwndChildAfter,
    LPCTSTR lpszClass,
    LPCTSTR lpszWindow
);

hwndParentQ指向一个待搜烦H口的父H?/p>

hwndChildAfterQ子H口的句柄?/p>

lpszClassQ窗口的cd?/p>

lpszWindowQ窗口的标题名?/p>

例如Q本CZ工程要找C个对话框里的~辑框,q对q个~辑框进行注入。查找过E如下:

    HWND hWndChild = NULL;
    while(1)
    {
        // 查找对话框窗口,且这个对话框H口的标题名?#8220;TestDlg”
        HWND hDlg = FindWindowEx(0, NULL, "#32770", "TestDlg");
        if(hDlg == NULL)
        {
            printf("没有扑ֈ该对话框H口!\n");
            exit(1);
        }
        else
        {
            // 查找q个对话框窗口中的edit控g
            hWndChild = FindWindowEx(hDlg, NULL, "Edit",NULL);
            if(hWndChild != NULL)
            {
                break; // 扑ֈq个~辑框,现在要对q个~辑框进行注?
            }
        }
    }

    // Ҏ查找出的H口Q查询进E?
    DWORD dwQQGameId;
    HANDLE hProcessQQGame;
    if(!GetWindowThreadProcessId(hWndChild,&dwQQGameId))
    {
        printf("Error in GetWindowThreadProcessId():%d\n",GetLastError());
        exit(1);
    }
扑ֈq个q程后,然后p对这个进E进行注入。但是,你别忘记了,当你在其他进E中获取另外q程的窗口句柄,你是没有办法操作q个句柄的。ؓ什么呢Q每个进E都被赋予它自己的虚拟地址I间。对? 2位进E来_q个地址I间? G BQ因
? 2位指针可以拥有从0 x 0 0 0 0 0 0 0 0? x F F F F F F F F之间的Q何一个倹{这使得一个指针能够拥? 294 967 296个g的一个|它覆盖了一个进E的4 G B虚拟I间的范围。对? 4位进E来_q个地址I间? 6 E BQ? 01 8字节Q,因ؓ6 4位指针可以拥有从0 x 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0? x F F F F F F F F F F F F F F F F之间的Q何倹{这使得一个指针可以拥?8 446 744 073 709 551 616个g的一个|它覆盖了一个进E的1 6 E B虚拟I间的范围。这是相当大的一个范围。由于每个进E可以接收它自己的私有的地址I间Q因此当q程中的一个线E正在运行时Q该U程可以讉K只属于它的进E的内存。属于所有其他进E的内存则隐藏着Qƈ且不能被正在q行的线E访问。注意在Windows 2000中,属于操作pȝ本n的内存也是隐藏的Q正在运行的U程无法讉K。这意味着U程常常不能讉K操作pȝ的数据。Windows 98中,属于操作pȝ的内存是不隐藏的Q正在运行的U程可以讉K。因此,正在q行的线E常常可以访问操作系l的数据Q也可以破坏操作pȝQ从而有可能D操作pȝ崩溃Q。在Windows 98中,一个进E的U程不可能访问属于另一个进E的内存。前面说q,每个q程有它自己的私有地址I间。进EA可能有一个存攑֜它的地址I间中的数据l构Q地址? x 1 2 3 4 5 6 7 8Q而进EB则有一个完全不同的数据l构存放在它的地址I间中,地址? x 1 2 3 4 5 6 7 8。当q程A中运行的U程讉K地址? x 1 2 3 4 5 6 7 8的内存时Q这些线E访问的是进EA的数据结构。当q程B中运行的U程讉K地址? x 1 2 3 4 5 6 7 8的内存时Q这些线E访问的是进EB的数据结构。进EA中运行的U程不能讉Kq程B的地址I间中的数据l构Q反之亦然?/p>

q样看来Q若惛_q个H口句柄q行操作Q得x设法使我们能够进入到原宿主进E中Q然后执行我们的操作。这个就好象一个寄生虫惌破坏Z的机能,必须得进入我们的体内Q寄生在我们的组l上才能够生作用。现在关键是如何寄生到宿M呢?

通常QQ何进E都可以通过LoadLibrary动态地加蝲DLLQ但是我们如何强制一个外部进E调用该函数呢?{案是CreateRemoteThread?br>让我们先来看看LoadLibrary和FreeLibrary的函数声明:

HINSTANCE LoadLibrary(
  LPCTSTR lpLibFileName   // address of filename of library module
);

BOOL FreeLibrary(
  HMODULE hLibModule      // handle to loaded library module
);

再和CreateRemoteThread的线E过E(thread procedureQThreadProc比较一下:
DWORD WINAPI ThreadProc(
  LPVOID lpParameter   // thread data
);

    你会发现所有的函数都有同样的调用约定(calling conventionQ、都接受一?2位的参数q且q回值类型的大小也一栗也是_我们可以把LoadLibrary/FreeLibrary的指针作为参C递给CrateRemoteThread?/p>

    然而,q有两个问题Q参考下面对CreateRemoteThread的说明)

    1Q?传递给ThreadProc的lpStartAddress 参数必须E进E中的线E过E的起始地址?br>    2Q?如果把ThreadProc的lpParameter参数当做一个普通的32位整敎ͼFreeLibrary把它当做HMODULEQ那么没有如何问题,但是如果把它当做一个指针(LoadLibrary把它当做一个char*Q,它就必须指向q程q程中的内存数据?/p>

    W一个问题其实已l迎刃而解了,因ؓLoadLibrary和FreeLibrary都是存在于kernel32.dll中的函数Q而kernel32可以保证M“正常”q程中都存在Q且其加载地址都是一L。(参看附录AQ于是LoadLibrary/FreeLibrary在Q何进E中的地址都是一LQ这׃证了传递给q程q程的指针是个有效的指针?/p>

    W二个问题也很简单:把DLL的文件名QLodLibrary的参敎ͼ用WriteProcessMemory复制到远E进E?/p>

    所以,使用CreateRemoteThread和LoadLibrary技术的步骤如下Q?br>    1Q?得到q程q程的HANDLEQ用OpenProcessQ?br>    2Q?在远E进E中为DLL文g名分配内存(VirtualAllocExQ?br>    3Q?把DLL的文件名Q全路径Q写到分配的内存中(WriteProcessMemoryQ?br>    4Q?使用CreateRemoteThread和LoadLibrary把你的DLL映射q远E进E?br>    5Q?{待q程U程l束QWaitForSingleObjectQ,即等待LoadLibraryq回。也是说当我们的DllMainQ是以DLL_PROCESS_ATTACH为参数调用的Q返回时q程U程也就立即l束了?br>    6Q?取回q程U程的结束码QGetExitCodeThtreadQ,即LoadLibrary的返回值――我们DLL加蝲后的基地址QHMODULEQ?br>    7Q?释放W?步分配的内存QVirtualFreeExQ?br>    8Q?用CreateRemoteThread和FreeLibrary把DLL从远E进E中卸蝲。调用时传递第6步取得的HMODULElFreeLibraryQ通过CreateRemoteThread的lpParameter参数Q?br>    9Q?{待U程的结束(WaitSingleObjectQ?/p>

主要代码如下Q?/p>

#include<stdio.h>
#include<conio.h>
#include<windows.h>

void main()
{
    HWND hWndChild = NULL;
    while(1)
    {
        // 查找对话框窗口,且这个对话框H口的标题名?#8220;TestDlg”
        HWND hDlg = FindWindowEx(0, NULL, "#32770", "TestDlg");
        if(hDlg == NULL)
        {
            printf("没有扑ֈ该对话框H口!\n");
            exit(1);
        }
        else
        {
            // 查找q个对话框窗口中的edit控g
            hWndChild = FindWindowEx(hDlg, NULL, "Edit",NULL);
            if(hWndChild != NULL)
            {
                break; // 扑ֈq个~辑框,现在要对q个~辑框进行注?
            }
        }
    }

    // Ҏ查找出的H口Q查询进E?
    DWORD dwQQGameId;
    HANDLE hProcessQQGame;
    if(!GetWindowThreadProcessId(hWndChild,&dwQQGameId))
    {
        printf("Error in GetWindowThreadProcessId():%d\n",GetLastError());
        exit(1);
    }


    HINSTANCE hDll = NULL;
    typedef void(*LP_SET_HEDIT_FUN)(HWND);
    LP_SET_HEDIT_FUN m_SethEdit = NULL;
    char DllPath[MAX_PATH] = "D:\\q程注入试工程\\Bin\\automessagedll.dll";
    hDll = LoadLibrary(DllPath);
    if(hDll)
    {
        m_SethEdit = (LP_SET_HEDIT_FUN)GetProcAddress(hDll,"SethEdit");
    }
    if(m_SethEdit)
    {
        m_SethEdit(hWndChild);
    }
    else
    {
        printf("Can not load SethEdit in the dll(%d).\n",GetLastError());
    }

 

    if( (hProcessQQGame = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwQQGameId)) == NULL)
    {
        printf("Error in OpenProcess():%d\n",GetLastError());
        getch();
        exit(1);
    }

    int cb = (1+lstrlen(DllPath))* sizeof(char);

    char* RemoteLibFile = (char*)VirtualAllocEx(hProcessQQGame,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
    if(RemoteLibFile == NULL)
    {
        printf("Error in VirtualAllocEx():%d\n",GetLastError());
        getch();
        exit(1);
    }
    if( (WriteProcessMemory(hProcessQQGame,RemoteLibFile,(LPVOID)DllPath,cb,NULL)) == 0)
    {
        printf("Error in WriteProcessMemory():%d\n",GetLastError());
        getch();
        exit(1);
    }


    PTHREAD_START_ROUTINE pfnStartAddr;
    pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"),"LoadLibraryA");


    HANDLE hThread = CreateRemoteThread(hProcessQQGame,NULL,0,pfnStartAddr,RemoteLibFile,0,NULL);
    if(hThread == NULL)
    {
        printf("Error in CreateRemoteThread():%d",GetLastError());
        getch();
        exit(1);
    }

    WaitForSingleObject(hThread,INFINITE);


    CloseHandle(hThread);
    VirtualFreeEx(hProcessQQGame,RemoteLibFile,0,MEM_RELEASE);
    CloseHandle(hProcessQQGame);
}

 

本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/kissyfish/archive/2008/12/07/3462055.aspx



lhking 2010-06-23 15:33 发表评论
]]>
C++ 下蝲文ghttp://www.shnenglu.com/lhking/archive/2010/06/23/118569.htmllhkinglhkingWed, 23 Jun 2010 07:27:00 GMThttp://www.shnenglu.com/lhking/archive/2010/06/23/118569.htmlhttp://www.shnenglu.com/lhking/comments/118569.htmlhttp://www.shnenglu.com/lhking/archive/2010/06/23/118569.html#Feedback0http://www.shnenglu.com/lhking/comments/commentRss/118569.htmlhttp://www.shnenglu.com/lhking/services/trackbacks/118569.html下蝲文g要用到操作系l的API函数Q下面是一个WINDOWSpȝ中的实现Q?/p>

//---------------------------------------------------------------------------
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#define MAXBLOCKSIZE 1024
#pragma comment( lib, "wininet.lib" ) ;

void download(const char *Url,const char *save_as)/*Url指向的地址的文件下载到save_as指向的本地文?/
{
 byte Temp[MAXBLOCKSIZE];
 ULONG Number = 1;

 FILE *stream;
 HINTERNET hSession = InternetOpen(_T("RookIE/1.0"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
 if (hSession != NULL)
 {
  HINTERNET handle2 = InternetOpenUrl(hSession,_T(Url), NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);
  if (handle2 != NULL)
  {


   if( (stream = fopen( save_as, "wb" )) != NULL )
   {
    while (Number > 0)
    {
     InternetReadFile(handle2, Temp, MAXBLOCKSIZE - 1, &Number);

     fwrite(Temp, sizeof (char), Number , stream);
    }
    fclose( stream );
   }

   InternetCloseHandle(handle2);
   handle2 = NULL;
  }
  InternetCloseHandle(hSession);
  hSession = NULL;
 }
}

int main(int argc, char* argv[]){

 download("*调用CZQ下载百度的首页到c:\index.html文g*/
 return 0;
}

 



lhking 2010-06-23 15:27 发表评论
]]>
C++ dll中用定时器http://www.shnenglu.com/lhking/archive/2010/06/23/118568.htmllhkinglhkingWed, 23 Jun 2010 06:57:00 GMThttp://www.shnenglu.com/lhking/archive/2010/06/23/118568.htmlhttp://www.shnenglu.com/lhking/comments/118568.htmlhttp://www.shnenglu.com/lhking/archive/2010/06/23/118568.html#Feedback0http://www.shnenglu.com/lhking/comments/commentRss/118568.htmlhttp://www.shnenglu.com/lhking/services/trackbacks/118568.htmlҎ一Q?br>SetTimer(NULL, 0, 1000, (TIMERPROC)Timer2Proc);

VOID CALLBACK Timer2Proc(
       HWND hWnd, // handle of window for timer messages
       UINT uMsg, // WM_TIMER message
       UINT idEvent, // timer identifier
       DWORD dwTime // current system time
       )
{
 return;
}

Ҏ二:
// DLL中的U程函数可以象这样用Timer
UINT ThreadProc(LPVOID)
{

 SetTimer(NULL, 1, 5000, NULL);
 MSG msg;
 // PeekMessage 强制pȝU程建立消息?br> PeekMessage(&msg, NULL, NULL, NULL, FALSE);
 while (GetMessage(&msg, NULL, NULL, NULL))
 {
  switch (msg.message)
  {
  case WM_TIMER:
   {
    // q里?U钟执行一?br>   }
   break;
  }
  //TranslateMessage(&msg);
  //DispatchMessage(&msg);
 }
 KillTimer(NULL, 1);
 return 0;
}

Ҏ三:
创徏一个线E? 反复ȝl时间不可以了? 如果定时要求不严,用Sleep可以了
UINT TimerThread(LPVOID pama)
{
 UINT oldTickCount, newTickCount;
 oldTickCount = GetTickCount();
 while(TRUE)
 {
  while(TRUE)
  {
   newTickCount = GetTickCount();
   if(newTickCount - oldTickCount >= 100)
   {
    oldTickCount = newTickCount;
    break;
   }
  }
  TimeProc();
 }
 return 0;
}
大约?00ms 调用一ơTimeProc();



lhking 2010-06-23 14:57 发表评论
]]>
What are the differences between MFC and Win32 Applicationhttp://www.shnenglu.com/lhking/archive/2010/06/22/118449.htmllhkinglhkingTue, 22 Jun 2010 03:43:00 GMThttp://www.shnenglu.com/lhking/archive/2010/06/22/118449.htmlhttp://www.shnenglu.com/lhking/comments/118449.htmlhttp://www.shnenglu.com/lhking/archive/2010/06/22/118449.html#Feedback0http://www.shnenglu.com/lhking/comments/commentRss/118449.htmlhttp://www.shnenglu.com/lhking/services/trackbacks/118449.html MFC is basicly a library of OO wrapper classes that wrap the Win32 api, and provide objects for the basic window components (windows, buttons, checkboxes etc..). Essentially it is the win32 api objectified.

Also MFC provides some classes that resemble classes found in the STL. As MFC was made before STL was fully standardised.

My knowledge is incomplete. But that is the basic Idea.



 User Rating: 1019   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

The difference between Win32 and MFC are pretty straightforward:

The Windows API (Win32) uses a C interface to access windows functionality. It requires that you write all of your own code to manage windows and message handling. It is quite straightforward but you will need a good reference, like MSDN, and some good tutorials or samples to get started.

In contrast, MFC, which stands for Microsoft Foundation Classes, are a collection of C++ classes which encapsulate the Win32 API. MFC has some wizards which make the initial creation of a program quick and easy, but I have to admit the learning curve of MFC can sometimes be frustrating as Microsoft seems to have done everything in a way that can at times seem counter-intuitive.

Whenever I write an application I write it in MFC but I have been writing applications in MFC for a long time. If all you want is a message loop and a window handle for a game, use Win32. If you want to write a larger application like an editor, maybe MFC is the right tool.

Ideally, I would suggest skipping both Win32 and MFC and writing tools in .NET. I do not have any personal experience in it but people I work with sure can get a lot done using it. It may well be worth investigation.

Best of luck,

- S

 User Rating: 1352   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Quote:
Original post by Sphet

Whenever I write an application I write it in MFC but I have been writing applications in MFC for a long time. If all you want is a message loop and a window handle for a game, use Win32. If you want to write a larger application like an editor, maybe MFC is the right tool.

- S


I am planning to write an interactive 3D environment does that mean using WIN32 application is a better tool for it?

also is it possible to use openGL for oject creation and DirectXinput for the interactive control?
please give me some suggestion



millions of thanks

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Quote:
Original post by muimui1911
I am planning to write an interactive 3D environment does that mean using WIN32 application is a better tool for it?

For a game Win32 is usually better.
I think I have also heard that MFC doesn't work well in fullscreen.

Quote:
Original post by muimui1911
also is it possible to use openGL for oject creation and DirectXinput for the interactive control?

You can render with opengl and use directinput for input.

____________________________________________________________
Programmers Resource Central

 User Rating: 1107   |  Rate This User  Send Private MessageView ProfileView GD Showcase Entries Report this Post to a Moderator | Link

what about mouse movement like shooting games?

how can i do that, please give me some direction

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

You can use directinput for mouse movement. Or you can use GetCursorPos(POINT *p);

____________________________________________________________
Programmers Resource Central

 User Rating: 1107   |  Rate This User  Send Private MessageView ProfileView GD Showcase Entries Report this Post to a Moderator | Link

How do i use that? can you give me some example and much clearer direction

millions of thanks

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

msdn
Though if you want a camera class look here and here.


lhking 2010-06-22 11:43 发表评论
]]>
c/c++中指针学习的两个l好例子-C/C++指针学习http://www.shnenglu.com/lhking/archive/2010/06/21/118405.htmllhkinglhkingMon, 21 Jun 2010 15:02:00 GMThttp://www.shnenglu.com/lhking/archive/2010/06/21/118405.htmlhttp://www.shnenglu.com/lhking/comments/118405.htmlhttp://www.shnenglu.com/lhking/archive/2010/06/21/118405.html#Feedback0http://www.shnenglu.com/lhking/comments/commentRss/118405.htmlhttp://www.shnenglu.com/lhking/services/trackbacks/118405.html
  指针学习不好关键是概念不清造成的,说的单点是书没有认真看Q指针的学习犹如人在学习饶口令不多看多学多练是不行的Q下面是两个很经典的例子Q很多书上都?对于学习的重点在于理?x和x的理解,他们q不相同Q?x所表示的其实就是变量a本nQx表示的是变量a在内存中的地址Q如果想明白可以输出观察cout<<*x"|"x;Q当定义了int *x;后对x=&a的理解的问题。仔l阅d联系下面的两个例子我x针问题就不是隄了!

#include <stdio.h>

main()
{
int a,b; /* 定义a,b两个整Ş变量用于输入两个整数 */
int *point_1,*point_2,*temp_point; /* 定义三个指针变量 */
scanf("%d,%d",&a,&b); /* 格式化输入a,b的?*/
point_1=&a; /* 把指针变量point_1的值指向变量a的地址 */
point_2=&b; /* 把指针变量point_2的值指向变量b的地址 */
if (a<b)
{
     temp_point=point_1; /* q里的temp_point是用于时存储point_1的g是变量a的地址?*/
     point_1=point_2; /* 把point_2的D予point_1 */
     point_2=temp_point;
     /* ׃point_1的值已l改变无法找?利用前面临时存储的也是temp_point扑֛原point_1的D予point_2,打到把point_1和point_2值对换的目的*/
}
printf("%d,%d",*point_1,*point_2); /* 利用*point_1?point_2也就是分辨指向b和a的方法把值显C爱屏q上 */
}

/* 此题需要注意和了解是的此法q没有改变变量a,b的值只是利用指针变量分别存储a和b的地址,然后再把那两个指针变量的值对换一下其实就是存储在
指针变量里面a与b的地址Ҏ,在利?point_1?point_2的方式把调换后的值显C出来这里的*point_1实际是a,此中法q真的改变a,b的?而是
利用指针q行地址交换辑ֈ大小排序的目?
*/



#include <stdio.h>

main()
{
int a,b; /* 定义a,b两个整Ş变量用于输入两个整数 */
int *point_1,*point_2; /* 定义三个指针变量 */
scanf("%d,%d",&a,&b); /* 格式化输入a,b的?*/
point_1 = &a; /* 把指针变量point_1的值指向变量a的地址 */
point_2 = &b; /* 把指针变量point_2的值指向变量b的地址 */
compositor(point_1,point_2); /* 调用自定义的排序涉|,把a,b的地址传递给point_1和point_2 */
printf("%d,%d",a,b); /* 打印出a,b的?*/
}

static compositor(p1,p2)
int *p1,*p2; /* 定义形式参数p1,p2为指针变?*/
{
int temp; /* 建立临时存储变量 */
     if (*p1<*p2) /* 如果*p1<p2,注意q里?p1?p2其实是a和b */
     {
         temp = *p1; /* 利用变量temp用于临时存储*p1和就是a的?*/
         *p1 = *p2; /* ?p1的g是a的值换?p2的g是b的?{h于a=b */
         *p2 = temp; /* ?p2的g是temp的值等价于b=temp */
     }
}

/* 注意:此题与上题不同的?直接改变了a于b的D到真实改变的目的 */



lhking 2010-06-21 23:02 发表评论
]]>
VC常用数据cd转换详解http://www.shnenglu.com/lhking/archive/2010/06/21/118404.htmllhkinglhkingMon, 21 Jun 2010 14:59:00 GMThttp://www.shnenglu.com/lhking/archive/2010/06/21/118404.htmlhttp://www.shnenglu.com/lhking/comments/118404.htmlhttp://www.shnenglu.com/lhking/archive/2010/06/21/118404.html#Feedback0http://www.shnenglu.com/lhking/comments/commentRss/118404.htmlhttp://www.shnenglu.com/lhking/services/trackbacks/118404.htmlVC常用数据cd转换详解
我们先定义一些常见类型变量借以说明
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;
一、其它数据类型{换ؓ字符?/font>

短整?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串转换为其它数据类?br>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变量?/font>
四、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落里的具体说明?/font>
CComBSTR与_bstr_t对大量的操作W进行了重蝲Q可以直接进?,!=,=={操作,所以用非常方ѝ?br>特别是_bstr_t,大家使用它?/font>

五、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; ///赋?/font>
对于不马上赋值的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字符丌Ӏ?/font>
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);
八、其?/font>
Ҏ息的处理中我们经帔R要将WPARAM或LPARAM{?2位数据(DWORD)分解成两?6位数据(WORD),例如Q?br>LPARAM lParam;
WORD loValue = LOWORD(lParam);///取低16?br>WORD hiValue = HIWORD(lParam);///取高16?/font>

对于16位的数据(WORD)我们可以用同LҎ分解成高低两?位数?BYTE),例如:
WORD wValue;
BYTE loValue = LOBYTE(wValue);///取低8?br>BYTE hiValue = HIBYTE(wValue);///取高8?/font>

两个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); ///得到兰颜?/font>

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



lhking 2010-06-21 22:59 发表评论
]]>
þþþƷ鶹| ھƷŷþþƷ| þˬˬav| þɬۺ| þþþþëƬѲ| þñþۺ| 97Ʒ˾þþô߽ | þþþþ޾Ʒ| þþƷư| 2020˾þþƷ| þùһ| ݺɫþþۺƵպ| þþžȫ| þþþŷղAV| ˾ƷۺϾþþ| þþþþԻAV| 99Ʒ˾þþô߽| Ļþи | 99þóĻ| ˾þô߽Ʒ | 91þþƷ91þɫ| þþƷĻ| ۺϾþþƷ| 72ŷþþþôƽ| þۺɫݺ| ݾƷŮ˾þþþþ| þþþó˾ƷĻ| ھƷþþþӰԺ˾| ˳վþ99ȹ| þù˾Ʒ| ƷþþþӰԺɫ| þþþ޾Ʒ| ٸþĻ| պһþ99 | 69SEXþþƷ鶹| ޾ƷþרӰҵ| Ʒþþþ| 2021þþƷѹۿ| þþþø߳ۺӰԺ| ޹ŮƷþþþá| ޾Ʒרþþ|