• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Re:誰知道禁用USB端口的函數(shù)啊!?! 是不是要自己寫方法哦!
            http://www.codeproject.com/system/EnumDevices.asp
            http://www.codeproject.com/system/change_drive_sn.asp
            http://www.codeproject.com/system/installed_programs.asp
            http://www.codeproject.com/system/enum_display_modes.asp
            http://www.codeproject.com/system/serial_portsenum_fifo.asp
            1Minimize any window to system tray using Windows Hook
            http://www.codeproject.com/system/DevicePropertySheet.asp
            http://www.codeproject.com/system/chaiyasit_t.asp
            http://www.codeproject.com/system/DevMgr.asp     001
            http://www.codeproject.com/system/eject_cdrom.asp
            http://www.codeproject.com/system/serviceskeleton.asp    002
            http://www.codeproject.com/useritems/HwDetect.asp    003








            Re:誰知道禁用USB端口的函數(shù)啊!?! 是不是要自己寫方法哦!
            我做了個MP3的量產(chǎn)軟件,當對MP3的文件download完成后會將MP3安全移除。
            問題是:我用GUID{0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}會將USB鍵盤和USB鼠標全都枚舉出來,這樣我就無法區(qū)分誰是MP3,誰是USB鍵盤和鼠標了。雖然枚舉時我可以得到PID和VID,但是我們的PID和VID可能會被代理商更改,所以也就不能通過PID和VID來區(qū)分了,不知PC上的安全刪除U盤是怎樣做到的,PC應(yīng)該可以將盤符和對應(yīng)的設(shè)備對應(yīng)起來,且能用唯一的標識來區(qū)分每臺設(shè)備,情況緊急,求求各位高手拉我一把吧,非常感謝!

            我的代碼如下:
            void CLogicDriveList::RemoveDevice(size_t index)
            {
            char szDevDesc[256] = {0};
            HDEVINFO hDevInfo;
            string Prod;
            string Rev;

            //遍歷所有的設(shè)備
            hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_DEVICE, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE) if ( INVALID_HANDLE_VALUE == hDevInfo)return;

            SP_DEVINFO_DATA devInfoData;
            devInfoData.cbSize = sizeof(devInfoData);

            int Index = 0;
            while(SetupDiEnumDeviceInfo(hDevInfo, Index++, &devInfoData))
            {
            //獲取設(shè)備ID
            std::string devId;
            memset(szDevDesc, 0, sizeof(szDevDesc));
            devInfoData.cbSize = sizeof(devInfoData);

            CM_Get_Device_ID(devInfoData.DevInst, szDevDesc, sizeof(szDevDesc),0);
            devId = szDevDesc;
            cout<<devId<<endl;
            //比較設(shè)備ID
            if(這里該怎樣填呢?)
            {
            if(EjectDevice(devInfoData))
            {
            cout<<"Remove device "<<m_LogicDrives [index].Symbol<<": ok"<<endl;
            break;
            }
            else
            cout<<"Remove device "<<m_LogicDrives[index].Symbol<<": fail"<<endl;
            }
            }
            }

            bool CLogicDriveList::EjectDevice(const SP_DEVINFO_DATA &devInfoData)
            {
            PNP_VETO_TYPE   pnpvietotype;  
            char vetoname[MAX_PATH] = {0};  
            CONFIGRET cr = CM_Request_Device_Eject(devInfoData.DevInst,  
                                    &pnpvietotype,
            vetoname,
            MAX_PATH,
            0);  
            return CR_SUCCESS==cr;
            }
            posted @ 2011-01-26 10:44 wrh 閱讀(976) | 評論 (0)編輯 收藏
            void   CRegExplorerView::EnumerateValues(HKEY   hKey,   LPCTSTR   cstrKey) 
            { 
             static   HKEY   hLastKey   =   hKey; 
             LONG   lResult; 
             DWORD   dwIndex   =   0; 
             HKEY   hCurKey   =   hKey; 
             DWORD   dwKeyType;   
             DWORD   dwKeyDataLength,   dwKeyNameLen; 
             LPBYTE   pbbinKeyData   =   NULL;   
             TCHAR   *tcKeyName   =   NULL; 
             TCHAR   tcDataType[1024]   =   _T( " "); 
             lResult   =   RegOpenKeyEx(hCurKey,   cstrKey,   0,   KEY_QUERY_VALUE   ,   &hKey); 
             if(lResult   !=   ERROR_SUCCESS) 
              return; 
             DWORD   lNoOfValues   =   0; 
             DWORD   lLongestKeyNameLen   =   1; 
             DWORD   lLongestDataLen   =   1; 

             lResult   =   RegQueryInfoKey(hKey,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   &lNoOfValues,   &lLongestKeyNameLen,   &lLongestDataLen,NULL,   NULL); 

             if(lResult   !=   ERROR_SUCCESS) 
              return; 
             hLastKey   =   hKey; 
             lLongestKeyNameLen++; 
             lLongestDataLen++; 
             tcKeyName   =   new   TCHAR[lLongestKeyNameLen]; 
             pbbinKeyData   =   new   BYTE[lLongestDataLen]; 
             CString   cstrFinalData,   cstrTemp; 
             while(TRUE) 
             { 
              memset(pbbinKeyData,   0,   lLongestDataLen); 
              memset(tcKeyName,   0,   lLongestKeyNameLen); 
              dwKeyType   =   dwKeyDataLength   =   dwKeyNameLen   =   0; 
              dwKeyNameLen   =   lLongestKeyNameLen; 
              dwKeyDataLength   =   lLongestDataLen; 
              lResult   =   RegEnumValue(hKey,   dwIndex,   tcKeyName,   &dwKeyNameLen,   NULL,   &dwKeyType,   pbbinKeyData,   &dwKeyDataLength); 
              if(lResult   ==   ERROR_NO_MORE_ITEMS) 
               break; 
              AddRegistryItem(tcKeyName,   dwKeyType,   pbbinKeyData,   dwKeyDataLength,   dwIndex);//顯示數(shù)據(jù)于ListView 
              dwIndex++; 
             } 
             RegCloseKey(hKey); 
             delete   tcKeyName; 
             delete   pbbinKeyData; 
            }
            posted @ 2011-01-05 13:27 wrh 閱讀(333) | 評論 (0)編輯 收藏
            請教各位: 
              用RegEnumKeyEx枚舉一個鍵下的所有子鍵,例如HKEY_LOCAL_MACHINE\Software\ListItem下有6個子鍵,分別是111,432fdksaf,fd3425,fd5432,89342,tewjfds,用RegEnumKeyEx可以枚舉出后3個子鍵(我是從后向前進行的),但是只能得到后3個的全名,前3個就只能得到前2個或3個字母(例如:432fdksaf就只能得到432),不知道為什么,如果是從前向后進行就只能得到前3個的全名,后3個就只能前2個或3個字母了。
            這是一個簡單的例子。 
            查看 "http://注意這兩行 "的注釋處。:) 

            void   CRegistryView::OnButton3()   
            { 
            //   TODO:   Add   your   control   notification   handler   code   here 
            HKEY   hkey; 
            LPCSTR   data_Get= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run "; 
            long   ret0=::RegOpenKeyEx(HKEY_LOCAL_MACHINE,data_Get,0,KEY_ALL_ACCESS,&hkey); 
            if   (ret0!=ERROR_SUCCESS) 
            { 
            MessageBox( "Error! "); 
            return; 
            } 
            TCHAR   szBuffer[256]; 
            DWORD   dwSize=256; 
            ZeroMemory(szBuffer,256); 
            DWORD   dIndex; 
            dIndex=0L; 
            while(RegEnumValue(hkey,dIndex,szBuffer,&dwSize,NULL,NULL,NULL,NULL)==ERROR_SUCCESS) 
            { 
            MessageBox(szBuffer, " "); 
            dIndex++; 
            ZeroMemory(szBuffer,256);   //注意這兩行 
            dwSize=256;                               // 
            } 
            return; 
            }

            問題解決了,不過我發(fā)現(xiàn)ZeroMemory(szBuffer,256);   這行可以不要要,只用重新設(shè)置dwSize的值就行了,因為RegEnumKeyEx是用&dwSize來調(diào)用的,完成后dwSize的值就會改變了,只要重新設(shè)置一下就行了,至于上面那行,應(yīng)該是為防止緩沖區(qū)中的值出錯而設(shè)置的。
            posted @ 2011-01-05 13:24 wrh 閱讀(1980) | 評論 (0)編輯 收藏

            #include "Wininet.h"
            #pragma comment(lib,"Wininet.lib")

            DWORD   flags;//上網(wǎng)方式  
            BOOL   m_bOnline;//是否在線  
               
            m_bOnline=InternetGetConnectedState(&flags,0);  

             if(m_bOnline)//在線  
            {  
                      int b;
                      if ( flags& INTERNET_CONNECTION_MODEM )
                      {
                             b = flags& INTERNET_CONNECTION_MODEM;
                      } 
                      else if ( flags&INTERNET_CONNECTION_LAN )
                      {
                             b = flags&INTERNET_CONNECTION_LAN;
                      }
                      else if ( flags& INTERNET_CONNECTION_PROXY )
                      {
                             b = flags& INTERNET_CONNECTION_PROXY;
                      }
                      switch(b)  
                      {  
                      case   INTERNET_CONNECTION_MODEM   :  
                              AfxMessageBox("在線:撥號上網(wǎng)");  
                              break;  
                      case   INTERNET_CONNECTION_LAN   :  
                              AfxMessageBox("在線:通過局域網(wǎng)");  
                              break;  
                      case   INTERNET_CONNECTION_PROXY   :  
                              AfxMessageBox("在線:代理");  
                              break;  
                      }  
                      if(flags&INTERNET_CONNECTION_MODEM_BUSY==INTERNET_CONNECTION_MODEM_BUSY)  
                              AfxMessageBox("MODEM被其他非INTERNET連接占用");  
            }  
            else  
                          AfxMessageBox("不在線");

            或者
            #include "Wininet.h"
            #pragma comment(lib,"Wininet.lib")

            DWORD   flags;//上網(wǎng)方式  
            BOOL   m_bOnline;//是否在線  
               
            m_bOnline=InternetGetConnectedState(&flags,0);  

             if(m_bOnline)//在線  
            {  
                      if ( flags& INTERNET_CONNECTION_MODEM )
                          AfxMessageBox("在線:撥號上網(wǎng)");  

                     else if ( flags&INTERNET_CONNECTION_LAN  )
                          AfxMessageBox("在線:通過局域網(wǎng)");

                     else if ( flags& INTERNET_CONNECTION_PROXY)
                          AfxMessageBox("在線:代理");
                    
                     else if ( flags&INTERNET_CONNECTION_MODEM_BUSY )
                           AfxMessageBox("MODEM被其他非INTERNET連接占用");   
            }  
            else  
                          AfxMessageBox("不在線");


            詳細說明:
            雖然MSDN中定義了7種參數(shù)類型,但實際中wininet.h頭文件中只對四種類型的值進行了定義
            7種類型:
            INTERNET_CONNECTION_LAN          局域網(wǎng)
            INTERNET_CONNECTION_MODEM        撥號上網(wǎng)
            INTERNET_CONNECTION_PROXY       代理
            INTERNET_CONNECTION_MODEM_BUSY  代理被占用

            INTERNET_CONNECTION_CONFIGURED    雖然可以聯(lián)網(wǎng),但當前不可用
            INTERNET_CONNECTION_OFFLINE     離線
            INTERNET_RAS_INSTALLED       RAS安裝

             Wininet.h頭文件中值定義:
            // Flags for InternetGetConnectedState
            #define INTERNET_CONNECTION_MODEM             1
            #define INTERNET_CONNECTION_LAN                2
            #define INTERNET_CONNECTION_PROXY             4
            #define INTERNET_CONNECTION_MODEM_BUSY      8

            然而實際的返回值卻并不是這四種值,本人現(xiàn)在是windows xp操作系統(tǒng),vc++ 6.0,局域網(wǎng)上網(wǎng),結(jié)果返回值是18,也就是10010,所以比INTERNET_CONNECTION_LAN的值2多了一位,也就是00010,返回值最高位1是多出來的,


            本文來自CSDN博客,轉(zhuǎn)載請標明出處:http://blog.csdn.net/sichuanpb/archive/2010/09/21/5898449.aspx

            posted @ 2011-01-02 18:04 wrh 閱讀(752) | 評論 (0)編輯 收藏
            Visual C++ 確定要使用的導(dǎo)出方法 (轉(zhuǎn)自MSDN)

            若要確定用于導(dǎo)出函數(shù)的方法(.def 文件或 __declspec(dllexport) 關(guān)鍵字),請回答下列問題:

            • 是否要一直添加附加的導(dǎo)出函數(shù)?

            • 誰要使用 DLL?例如,是由許多無法重新生成的可執(zhí)行文件使用的第三方 DLL 還是僅由可以輕松重新生成的應(yīng)用程序使用的 DLL?

            使用 .DEF 文件的優(yōu)缺點

            在 .def 文件中導(dǎo)出函數(shù)使您得以控制導(dǎo)出序號。當將附加的導(dǎo)出函數(shù)添加到 DLL 時,可以給它們分配更高的序號值(高于任何其他導(dǎo)出函數(shù))。當您進行此操作時,使用隱式鏈接的應(yīng)用程序不必與包含新函數(shù)的新導(dǎo)入庫重新鏈接。這非常重要,例如,在設(shè)計將由許多應(yīng)用程序使用的第三方 DLL 時。可以通過添加附加功能不斷地增強 DLL,同時確保現(xiàn)有應(yīng)用程序繼續(xù)正常使用新的 DLL。MFC DLL 是使用 .def 文件生成的。

            使用 .def 文件的另一個優(yōu)點是:可以使用 NONAME 屬性導(dǎo)出函數(shù),該屬性僅將序號放到 DLL 的導(dǎo)出表中。對具有大量導(dǎo)出函數(shù)的 DLL,使用 NONAME 屬性可以減小 DLL 文件的大小。有關(guān)編寫模塊定義語句的信息,請參見模塊定義語句的規(guī)則。有關(guān)序號導(dǎo)出的更多信息,請參見按序號而不是按名稱從 DLL 導(dǎo)出函數(shù)

            使用 .def 文件的主要缺點是:在 C++ 文件中導(dǎo)出函數(shù)時,必須將修飾名放到 .def 文件中,或者通過使用外部“C”用標準 C 鏈接定義導(dǎo)出函數(shù),以避免編譯器進行名稱修飾。

            如果需要將修飾名放到 .def 文件中,則可以通過使用 DUMPBIN 工具或 /MAP 鏈接器選項來獲取修飾名。請注意,編譯器產(chǎn)生的修飾名是編譯器特定的。如果將 Visual C++ 編譯器產(chǎn)生的修飾名放到 .def 文件中,則鏈接到 DLL 的應(yīng)用程序必須也是用相同版本的 Visual C++ 生成的,這樣調(diào)用應(yīng)用程序中的修飾名才能與 DLL 的 .def 文件中的導(dǎo)出名相匹配。

            使用 __declspec(dllexport) 的優(yōu)缺點

            使用 __declspec(dllexport) 非常方便,因為不必考慮維護 .def 文件和獲取導(dǎo)出函數(shù)的修飾名。例如,如果您設(shè)計的 DLL 供自己控制的應(yīng)用程序使用,則此方法很適用。如果通過新的導(dǎo)出函數(shù)重新生成 DLL,還必須重新生成應(yīng)用程序,因為如果使用不同版本的編譯器進行重新編譯,則導(dǎo)出的 C++ 函數(shù)的修飾名可能會發(fā)生變化。

            posted @ 2010-12-28 13:48 wrh 閱讀(648) | 評論 (0)編輯 收藏
            轉(zhuǎn)載自 yibansha0
            最終編輯 yibansha0

            調(diào)用DLL有兩種方法:靜態(tài)調(diào)用和動態(tài)調(diào)用.
            (一).靜態(tài)調(diào)用其步驟如下:
            1.把你的youApp.DLL拷到你目標工程(需調(diào)用youApp.DLL的工程)的Debug目錄下;
            2.把你的youApp.lib拷到你目標工程(需調(diào)用youApp.DLL的工程)目錄下;
            3.把你的youApp.h(包含輸出函數(shù)的定義)拷到你目標工程(需調(diào)用youApp.DLL的工程)目
            錄下;
            4.打開你的目標工程選中工程,選擇Visual C++的Project主菜單的Settings菜單;
            5.執(zhí)行第4步后,VC將會彈出一個對話框,在對話框的多頁顯示控件中選擇Link頁。然
            后在Object/library modules輸入框中輸入:youApp.lib
            6.選擇你的目標工程Head Files加入:youApp.h文件;
            7.最后在你目標工程(*.cpp,需要調(diào)用DLL中的函數(shù))中包含你的:#include "youApp.h "
            注:youApp是你DLL的工程名。
            2.動態(tài)調(diào)用其程序如下:
            動態(tài)調(diào)用時只需做靜態(tài)調(diào)用步驟1.
            {
            HINSTANCE hDllInst = LoadLibrary( "youApp.DLL ");
            if(hDllInst)
            {
            typedef DWORD (WINAPI *MYFUNC)(DWORD,DWORD);
            MYFUNC youFuntionNameAlias = NULL; // youFuntionNameAlias 函數(shù)別名
            youFuntionNameAlias = (MYFUNC)GetProcAddress
            (hDllInst, "youFuntionName ");
            // youFuntionName 在DLL中聲明的函數(shù)名
            if(youFuntionNameAlias)
            {
            youFuntionNameAlias(param1,param2);
            }
            FreeLibrary(hDllInst);
            }
            }

             

             

             

             

            原文出處: codeguru

            我正在學(xué)習(xí)DLLs,談不上對其有什么高屋建瓴的見解;本文只是(通過)編碼讓你看到并想知道代碼是如何運行的。在本文中,我假定你知道如何使用你的編譯器特性,比如設(shè)置目錄路徑等等。

             

            為了建立項目,請選擇Win32 控制臺項目(Win32 Console Application),并且在應(yīng)用程序設(shè)置標簽(the advanced tab)上,選擇DLL和空項目選項。DLLs可能并不如你想像的那樣難。首先寫你的頭文件(header file);稱為DLLTutorial.h。這個文件與其它頭文件一樣,其中只是一些函數(shù)的原型。

            #ifndef _DLL_TUTORIAL_H_
            #define _DLL_TUTORIAL_H_
            #include <iostream> #if defined DLL_EXPORT
            #define DECLDIR __declspec(dllexport)
            #else
            #define DECLDIR __declspec(dllimport)
            #endif

            extern "C"
            {
            DECLDIR int Add( int a, int b );
            DECLDIR void Function( void );
            }
            #endif

            前面兩行指示編譯器只包含這個文件一次。extern "C"告訴編譯器該部分可以在C/C++中使用。

            在VC++中這里有兩個方法來導(dǎo)出函數(shù):

                 1、使用__declspec,一個Microsoft定義的關(guān)鍵字。

                 2、創(chuàng)建一個模塊定義文件(Module-Definition File即.DEF)。第一種方法稍稍比第二種方法簡單些,但兩種都工作得很好。

            __declspec(dllexport)導(dǎo)出函數(shù)符號到在你的DLL中的一個存儲類。當下面一行被定義時我定義DECLDIR來運行這個函數(shù),

            #define DLL_EXPORT

            同時也導(dǎo)入函數(shù)如果下面一行

            #define DLL_EXPORT

            沒有在源文件中出現(xiàn)。在此情況下,你將導(dǎo)出函數(shù)Add(int a, int b)和Function()。

            現(xiàn)在,你需要寫一個將要稱為DLLTutorial.cpp的源文件。

            #include <iostream>
            #include "DLL_Tutorial.h"

            #define DLL_EXPORT extern "C"
            {
            DECLDIR int Add( int a, int b )
            {
            return( a + b );
            } DECLDIR void Function( void )
            {
            std::cout << "DLL Called!" << std::endl;
            } }

            這里你定義了(DLL中的)所有函數(shù)。Int Add(int a, int b)只簡單地將兩個數(shù)相加而void Function(void)只是在你的DLL被調(diào)用時(將信息)通知你。在我像你展示如何使用DLL前,我想告訴你一些關(guān)于模塊定義文件(.def)的內(nèi)容。

            模塊定義文件(.def)

            模塊定義文件是一個有著.def文件擴展名的文本文件。它被用于導(dǎo)出一個DLL的函數(shù),和__declspec(dllexport)很相似,但是.def文件并不是Microsoft定義的。一個.def文件中只有兩個必需的部分:LIBRARY 和 EXPORTS。讓我們先看一個基本的.def文件稍后我將解析之。

            LIBRARY dll_tutorial
            DESCRIPTION "our simple DLL"
            EXPORTS
            Add @1
            Function @2

            第一行,''LIBRARY''是一個必需的部分。它告訴鏈接器(linker)如何命名你的DLL。下面被標識為''DESCRIPTION''的部分并不是必需的,但是我喜歡把它放進去。該語句將字符串寫入 .rdata 節(jié)[據(jù) MSDN],它告訴人們誰可能使用這個DLL,這個DLL做什么或它為了什么(存在)。再下面的部分標識為''EXPORTS''是另一個必需的部分;這個部分使得該函數(shù)可以被其它應(yīng)用程序訪問到并且它創(chuàng)建一個導(dǎo)入庫。當你生成這個項目時,不僅是一個.dll文件被創(chuàng)建,而且一個文件擴展名為.lib的導(dǎo)出庫也被創(chuàng)建了。除了前面的部分以外,這里還有其它四個部分標識為:NAME, STACKSIZE, SECTIONS, 和 VERSION。我將不再在本文中涉及這些內(nèi)容,但是如果你在Internet上搜索,我想你將找到一些東西(譯注: MSDN2003上對模板定義文件各部分內(nèi)容有詳盡解釋,請參閱)。另外,一個分號(;)開始一個注解,如同''//''在C++中一樣。

            現(xiàn)在你已經(jīng)創(chuàng)建了你的DLL,你需要學(xué)習(xí)如何在一個應(yīng)用程序中使用它了。當這個DLL被生成后,它創(chuàng)建了一個.dll文件和一個.lib文件;這兩個都是你需要的。

            隱式鏈接

            這里有兩個方法來載入一個DLL;一個方法是捷徑另一個則相比要復(fù)雜些。捷徑是只鏈接到你.lib 文件并將.dll文件置入你的新項目的路徑中去。因此,創(chuàng)建一個新的空的Win32控制臺項目并添加一個源文件。將你做的DLL放入你的新項目相同的目錄下。

             

            #include <iostream>
            #include <DLLTutorial.h>

            int main()
            {
            Function();
            std::cout << Add(32, 58) << "\n";
            return(1);
            }

            你必需要鏈接到DLLTutorial.lib文件。我在項目屬性中設(shè)置了,但是你可能會用下面的語句代替:

            #pragma comment(lib, "DLLTutorial.lib")


            請注意我讓編譯器來查看我的DLL文件夾已獲得.lib文件同時讓它順便看下該目錄中的DLL頭文件。如果你不想這么做,你可以總是把他們放入你的新項目的目錄中并使用""(引號)而不是<>。這就是載入一個DLL的簡單方法。

            顯示鏈接

            難點的加載DLL的方法是有稍微有點復(fù)雜的。你將需要函數(shù)指針和一些Windows函數(shù)。但是,通過這種載入DLLs的方法,你不需要DLL的.lib或頭文件,而只需要DLL。下面列出一些代碼,我稍后將解析之。

            #include <iostream>
            #include <windows.h>

            typedef int (*AddFunc)(int,int);
            typedef void (*FunctionFunc)();

            int main()
            {
            AddFunc _AddFunc;
            FunctionFunc _FunctionFunc;
            HINSTANCE hInstLibrary = LoadLibrary("DLL_Tutorial.dll"); if (hInstLibrary == NULL)
            {
            FreeLibrary(hInstLibrary);
            }

            _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
            _FunctionFunc = (FunctionFunc)GetProcAddress(hInstLibrary, "Function"); if ((_AddFunc == NULL) || (_FunctionFunc == NULL))
            {
            FreeLibrary(hInstLibrary);
            } std::cout << _AddFunc(23, 43) << std::endl;
            _FunctionFunc(); std::cin.get(); FreeLibrary(hInstLibrary); return(1);
            }

            首先你會注意到:這里包括進了文件“windows.h”同時移走了“DLL_Tutorial.h”。原因很簡單:因為windows.h包含了一些Windows函數(shù),當然你現(xiàn)在將只需要其中幾個而已。它也包含了一些將會用到的Windows特定變量。你可以去掉DLL的頭文件(DLL_Tutorial.h)因為-如我前面所說-當你使用這個方法載入DLL時你并不需要它。

            下面你會看到:以下面形式的一小塊古靈精怪的代碼:

            typedef int (*AddFunc)(int,int);
            typedef void (*FunctionFunc)();

            這是函數(shù)指針。因為這是一個關(guān)于DLL的自學(xué)指南,深入探究函數(shù)指針超出了本指南的范圍;因此,現(xiàn)在我們只把它們當作DLL包含的函數(shù)的別名。我喜歡在尾部用“Func”命名之。(int,int)部分是這個函數(shù)的參數(shù)部分,比如,Add函數(shù)要獲得兩個整數(shù);因此,你需要它們(譯注:指(int,int)部分)作為函數(shù)指針的參數(shù)。Function函數(shù)沒有參數(shù),因此你讓它為空。main()部分中的前面兩行是聲明函數(shù)指針以使得你可以認為它們等同于DLL內(nèi)部的函數(shù)。我只是喜歡預(yù)先定義它們。

            一個HINSTANCE是一個Windows數(shù)據(jù)類型:是一個實例的句柄;在此情況下,這個實例將是這個DLL。你可以通過使用函數(shù)LoadLibrary()獲得DLL的實例,它獲得一個名稱作為參數(shù)。在調(diào)用LoadLibrary函數(shù)后,你必需查看一下函數(shù)返回是否成功。你可以通過檢查HINSTANCE是否等于NULL(在Windows.h中定義為0或Windows.h包含的一個頭文件)來查看其是否成功。如果其等于NULL,該句柄將是無效的,并且你必需釋放這個庫。換句話說,你必需釋放DLL獲得的內(nèi)存。如果函數(shù)返回成功,你的HINSTANCE就包含了指向DLL的句柄。

            一旦你獲得了指向DLL的句柄,你現(xiàn)在可以從DLL中重新獲得函數(shù)。為了這樣作,你必須使用函數(shù)GetProcAddress(),它將DLL的句柄(你可以使用HINSTANCE)和函數(shù)的名稱作為參數(shù)。你可以讓函數(shù)指針獲得由GetProcAddress()返回的值,同時你必需將GetProcAddress()轉(zhuǎn)換為那個函數(shù)定義的函數(shù)指針。舉個例子,對于Add()函數(shù),你必需將GetProcAddress()轉(zhuǎn)換為AddFunc;這就是它知道參數(shù)及返回值的原因。現(xiàn)在,最好先確定函數(shù)指針是否等于NULL以及它們擁有DLL的函數(shù)。這只是一個簡單的if語句;如果其中一個等于NULL,你必需如前所述釋放庫。

            一旦函數(shù)指針擁有DLL的函數(shù),你現(xiàn)在就可以使用它們了,但是這里有一個需要注意的地方:你不能使用函數(shù)的實際名稱;你必需使用函數(shù)指針來調(diào)用它們。在那以后,所有你需要做的是釋放庫如此而已。

            現(xiàn)在你知道了DLL的一些基本知識。你知道如何創(chuàng)建它們,你也知道如何用兩種不同的方法鏈接它們。這里仍然有更多的東西需要我們學(xué)習(xí),但我把它們留給你們自己探索了和更棒的作者來寫了。

            posted @ 2010-12-28 13:47 wrh 閱讀(428) | 評論 (0)編輯 收藏
            顯式(靜態(tài))調(diào)用:
            LIB   +   DLL   +   .H,注意.H中dllexport改為dllimport

            隱式(動態(tài))調(diào)用:
            DLL   +   函數(shù)原型聲明,先LoadLibrary,再GetProcAddress(即找到DLL中函數(shù)的地址),不用后FreeLibrary
            顯式(靜態(tài))調(diào)用:
            LIB   +   DLL   +   .H,注意.H中dllexport改為dllimport

            隱式(動態(tài))調(diào)用:
            DLL   +   函數(shù)原型聲明,先LoadLibrary,再GetProcAddress(即找到DLL中函數(shù)的地址),不用后FreeLibrary
            顯式(靜態(tài))調(diào)用:
            LIB   +   DLL   +   .H,注意.H中dllexport改為dllimport

            隱式(動態(tài))調(diào)用:
            DLL   +   函數(shù)原型聲明,先LoadLibrary,再GetProcAddress(即找到DLL中函數(shù)的地址),不用后FreeLibrary
            顯式(靜態(tài))調(diào)用:
            LIB   +   DLL   +   .H,注意.H中dllexport改為dllimport

            隱式(動態(tài))調(diào)用:
            DLL   +   函數(shù)原型聲明,先LoadLibrary,再GetProcAddress(即找到DLL中函數(shù)的地址),不用后FreeLibrary

            調(diào)用DLL有兩種方法:靜態(tài)調(diào)用和動態(tài)調(diào)用.
            (一).靜態(tài)調(diào)用其步驟如下:
            1.把你的youApp.DLL拷到你目標工程(需調(diào)用youApp.DLL的工程)的Debug目錄下;
            2.把你的youApp.lib拷到你目標工程(需調(diào)用youApp.DLL的工程)目錄下;
            3.把你的youApp.h(包含輸出函數(shù)的定義)拷到你目標工程(需調(diào)用youApp.DLL的工程)目
            錄下;
            4.打開你的目標工程選中工程,選擇Visual   C++的Project主菜單的Settings菜單;
            5.執(zhí)行第4步后,VC將會彈出一個對話框,在對話框的多頁顯示控件中選擇Link頁。然
            后在Object/library   modules輸入框中輸入:youApp.lib
            6.選擇你的目標工程Head   Files加入:youApp.h文件;
            7.最后在你目標工程(*.cpp,需要調(diào)用DLL中的函數(shù))中包含你的:#include   "youApp.h "
            注:youApp是你DLL的工程名。
            2.動態(tài)調(diào)用其程序如下:
            動態(tài)調(diào)用時只需做靜態(tài)調(diào)用步驟1.
            {
            HINSTANCE   hDllInst   =   LoadLibrary( "youApp.DLL ");
            if(hDllInst)
            {
            typedef   DWORD   (WINAPI   *MYFUNC)(DWORD,DWORD);
            MYFUNC   youFuntionNameAlias   =   NULL;   //   youFuntionNameAlias   函數(shù)別名
            youFuntionNameAlias   =   (MYFUNC)GetProcAddress
            (hDllInst, "youFuntionName ");
            //   youFuntionName   在DLL中聲明的函數(shù)名
            if(youFuntionNameAlias)
            {
            youFuntionNameAlias(param1,param2);
            }
            FreeLibrary(hDllInst);
            }
            }






            顯式(靜態(tài))調(diào)用:
            LIB   +   DLL   +   .H,注意.H中dllexport改為dllimport

            隱式(動態(tài))調(diào)用:
            DLL   +   函數(shù)原型聲明,先LoadLibrary,再GetProcAddress(即找到DLL中函數(shù)的地址),不用后FreeLibrary



            調(diào)用DLL,首先需要將DLL文件映像到用戶進程的地址空間中,然后才能進行函數(shù)調(diào)用,這個函數(shù)和進程內(nèi)部一般函數(shù)的調(diào)用方法相同。Windows提供了兩種將DLL映像到進程地址空間的方法:

            1. 隱式的加載時鏈接
            這種方法需要DLL工程經(jīng)編譯產(chǎn)生的LIB文件,此文件中包含了DLL允許應(yīng)用程序調(diào)用的所有函數(shù)的列表,當鏈接器發(fā)現(xiàn)應(yīng)用程序調(diào)用了LIB文件列出的某個函數(shù),就會在應(yīng)用程序的可執(zhí)行文件的文件映像中加入一些信息,這些信息指出了包含這個函數(shù)的DLL文件的名字。當這個應(yīng)用程序運行時,也就是它的可執(zhí)行文件被操作系統(tǒng)產(chǎn)生映像文件時,系統(tǒng)會查看這個映像文件中關(guān)于DLL的信息,然后將這個DLL文件映像到進程的地址空間。
            系統(tǒng)通過DLL文件的名稱,試圖加載這個文件到進程地址空間時,它尋找DLL 文件的路徑按照先后順序如下:
            ·程序運行時的目錄,即可執(zhí)行文件所在的目錄;
            ·當前程序工作目錄
            ·系統(tǒng)目錄:對于Windows95/98來說,可以調(diào)用GetSystemDirectory函數(shù)來得到,對于WindowsNT/2000來說,指的是32位Windows的系統(tǒng)目錄,也可以調(diào)用GetSystemDirectory函數(shù)來得到,得到的值為SYSTEM32。
            ·Windows目錄
            ·列在PATH環(huán)境變量中的所有目錄
            VC中加載DLL的LIB文件的方法有以下三種:
            ①LIB文件直接加入到工程文件列表中
            在VC中打開File View一頁,選中工程名,單擊鼠標右鍵,然后選中“Add Files to Project”菜單,在彈出的文件對話框中選中要加入DLL的LIB文件即可。
            ②設(shè)置工程的 Project Settings來加載DLL的LIB文件
            打開工程的 Project Settings菜單,選中Link,然后在Object/library modules下的文本框中輸入DLL的LIB文件。
            ③通過程序代碼的方式
            加入預(yù)編譯指令#pragma comment (lib,”*.lib”),這種方法優(yōu)點是可以利用條件預(yù)編譯指令鏈接不同版本的LIB文件。因為,在Debug方式下,產(chǎn)生的LIB文件是Debug版本,如Regd.lib;在Release方式下,產(chǎn)生的LIB文件是Release版本,如Regr.lib。
            當應(yīng)用程序?qū)LL的LIB文件加載后,還需要把DLL對應(yīng)的頭文件(*.h)包含到其中,在這個頭文件中給出了DLL中定義的函數(shù)原型,然后聲明。
            2 顯式的運行時鏈接  ,(我用的是此方法)
            隱式鏈接雖然實現(xiàn)較簡單,但除了必須的*.dll文件外還需要DLL的*.h文件和*.lib文件,在那些只提供*.dll文件的場合就無法使用,而只能采用顯式鏈接的方式。這種方式通過調(diào)用API函數(shù)來完成對DLL的加載與卸載,其能更加有效地使用內(nèi)存,在編寫大型應(yīng)用程序時往往采用此方式。這種方法編程具體實現(xiàn)步驟如下:
            ①使用Windows API函數(shù)Load Library或者MFC提供的AfxLoadLibrary將DLL模塊映像到進程的內(nèi)存空間,對DLL模塊進行動態(tài)加載。
            ②使用GetProcAddress函數(shù)得到要調(diào)用DLL中的函數(shù)的指針。
            ③不用DLL時,用Free Library函數(shù)或者AfxFreeLibrary函數(shù)從進程的地址空間顯式卸載DLL。
            例:在應(yīng)用程序中調(diào)用dll文件

            ——在應(yīng)用程序中要首先裝入dll后才能調(diào)用導(dǎo)出表中的函數(shù),例如用mfc

            創(chuàng)建基于對話框的工程test,并在對話框上放置"load"按鈕,先添加裝載代碼。
            1.首先在testdlg.cpp的首部添加變量設(shè)置代碼:

            //設(shè)置全局變量glibsample用于存儲dll句柄

            HINSTANCE  glibsample=null;   //如果定義成HANDLE類型,則出錯

            //第二個變量showme是指向dll
            庫中showme()函數(shù)的指針

            typedef int(* Showme)(void);

            Showme showme;

            2.利用classwizard為"load"按鈕添加裝載dll的代碼

            void ctestdlg::onloadbutton()

            {

            //要添加的代碼如下

            if(glibsample!=NULL)

            {

            AfxMessageBox("the sample.dll has already been load.");

            return;

            }

            //裝載sample.dll,未加路徑,將在三個默認路徑中尋找 (1)windows的系統(tǒng)目錄:\windows\system;

            //(2)dos中path所指出的任何目錄;

            //(3)程序所在的目錄;


            glibsample=Loadlibrary("sample.dll");

            //返回dll中showme()函數(shù)的地址

            showme=(Showme)GetProcAddress(glibsample,"showme");

            posted @ 2010-12-27 13:15 wrh 閱讀(3684) | 評論 (0)編輯 收藏
            可利用SDK   API:GetAdaptersInfo以及GetIfEntry實現(xiàn)。  
                    GetAdaptersInfo返回系統(tǒng)中的所有網(wǎng)卡信息。  
                    GetIfEntry則返回制定網(wǎng)口的速率、狀態(tài)等信息。  
                    如果覺得將相關(guān)數(shù)據(jù)結(jié)構(gòu)改造到VB下很痛苦的話,可編寫一個短小的DLL完成網(wǎng)口檢測工作,并僅返回檢測結(jié)果即可。  
                    VC代碼:  
                    DWORD   dwOutBufLen=0;  
                     
                      PIP_ADAPTER_INFO   pAdapterInfo=NULL,pAdapter=NULL;  
                     
                      MIB_IFROW   zSNMP;  
                     
                      char   sTemp[20];  
                     
                      int   iReturn;          
                     
                      iReturn=GetAdaptersInfo(pAdapterInfo,&dwOutBufLen);  
                     
                      if(iReturn!=ERROR_BUFFER_OVERFLOW)  
                     
                      {  
                     
                      return   0;  
                     
                      }  
                               
                      pAdapterInfo   =(PIP_ADAPTER_INFO)   HeapAlloc(GetProcessHeap(),   0,   dwOutBufLen);  
                     
                      iReturn=GetAdaptersInfo(pAdapterInfo,&dwOutBufLen);  
                     
                      if(iReturn!=ERROR_SUCCESS)  
                     
                      {  
                     
                      HeapFree(GetProcessHeap(),   0,   pAdapterInfo);  
                     
                      return   0;  
                     
                      }  
                     
                      pAdapter=pAdapterInfo;  
                     
                     
                     
                      //find   if   there   is   ppp   adapter  
                     
                      while(pAdapter!=NULL   )  
                     
                      {  
                     
                      zSNMP.dwIndex   =   pAdapter-> Index;  
                     
                      iReturn=GetIfEntry(&zSNMP);  
                     
                      if(iReturn!=NO_ERROR)  
                     
                      return   0;  
                     
                     
                     
                      m_iIfSpeed=zSNMP.dwSpeed/(1000*1000);  
                     
                      m_iIfAdminStatus=zSNMP.dwAdminStatus;  
                     
                      m_iIfOperStatus=zSNMP.dwOperStatus;  
                     
                      …  
                     
                      pAdapter=pAdapter-> Next;  
                     
                      }
            posted @ 2010-12-17 11:26 wrh 閱讀(1007) | 評論 (0)編輯 收藏
            #include <windows.h>
            #include <stdio.h>
            #include <iostream.h>
            #include "vfw.h"
            #pragma comment( lib, "vfw32.lib" )

            void main()
            {
              
                char strDeviceVersion[80];    //設(shè)備版本信息
                char strDeviceAndVersion[160];  //設(shè)備名和版本信息
                int nIndex;
                int nDriverCount = 0;                //支持的設(shè)備驅(qū)動程序個數(shù)
              
              
                for(nIndex=0; nIndex <9; nIndex++)
                {
                    if(capGetDriverDescription(nIndex,(LPSTR)strDeviceAndVersion,sizeof(strDeviceAndVersion),(LPSTR)strDeviceVersion,sizeof(strDeviceVersion)))
                    {
                        strcat(strDeviceAndVersion,",");
                        strcat(strDeviceAndVersion,strDeviceVersion);
                        nDriverCount++;                  //得到vfw設(shè)備信息及連的設(shè)備數(shù)量
                    }
                    else
                        break;
                }
                if (nDriverCount==0)
                    cout <<"沒有攝像頭"<<endl;
                else
                    cout <<"有攝像頭"<<endl;
            }
            posted @ 2010-12-17 11:20 wrh 閱讀(1138) | 評論 (0)編輯 收藏

            經(jīng)常看見網(wǎng)上有人問如何得到網(wǎng)線連上與拔出的狀態(tài),在這里介紹幾種方法,也許對大家會有所幫助

            第一種是通過OID進行查詢的方法

             DWORD dwObj, dwStatus, dwBytesRet;
             dwOIDCode = OID_GEN_MEDIA_CONNECT_STATUS;
             DeviceIoControl(hAdapter, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwOIDCode, sizeof(dwOIDCode), &dwStatus,sizeof(dwStatus), &dwBytesRet, NULL); 
             printf("state is:%d\n",dwStatus);

            dwStatus=0表示連上了,1代表未連上

            但是經(jīng)過我的測試,好像這里的狀態(tài)并不是代表網(wǎng)線的,而是代表網(wǎng)絡(luò)可用與不可用,網(wǎng)線插上,網(wǎng)絡(luò)正在連接,這種狀態(tài)下的網(wǎng)絡(luò)是不可用的

            第二種是通過WMI進行查詢,WMI的功能很強大的

             while (pEnumerator)
             {
              HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
               &pclsObj, &uReturn);

              if(0 == uReturn)
              {
               break;
              }
              VARIANT vtProp;
              hr = pclsObj->Get(L"NdisMediaConnectStatus", 0, &vtProp, 0, 0);
              if (vtProp.bstrVal)
              {
               NdisMediaConnectStatus++;
              }
              VariantClear(&vtProp);
             }

            經(jīng)過測試,這種方法可以得到網(wǎng)線的狀態(tài),如果要實時得到網(wǎng)線的連接狀態(tài)的話,可以開線程,當然資源充足的話也可以1秒查詢一次,但是這種方法在有多個網(wǎng)線的時候是不行的

            posted @ 2010-12-16 09:42 wrh 閱讀(2285) | 評論 (0)編輯 收藏
            僅列出標題
            共25頁: 1 2 3 4 5 6 7 8 9 Last 

            導(dǎo)航

            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            統(tǒng)計

            常用鏈接

            留言簿(19)

            隨筆檔案

            文章檔案

            收藏夾

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久人人爽人人爽人人片AV东京热| 久久亚洲精品国产精品婷婷 | 精品99久久aaa一级毛片| 精品久久久久久中文字幕| 99久久精品国产一区二区三区| 久久99热这里只有精品国产| 国内精品人妻无码久久久影院导航 | 久久亚洲美女精品国产精品| 18岁日韩内射颜射午夜久久成人| 性高朝久久久久久久久久| 久久亚洲精品成人无码网站| 国产精品久久国产精品99盘| 青青草原综合久久大伊人| 国产午夜免费高清久久影院| 亚洲Av无码国产情品久久| 66精品综合久久久久久久| 亚洲中文字幕久久精品无码APP| 99久久成人18免费网站| 人妻丰满AV无码久久不卡| 一本一本久久a久久精品综合麻豆| 精品999久久久久久中文字幕| 久久亚洲日韩看片无码| 四虎影视久久久免费| 国产综合精品久久亚洲| 久久伊人精品青青草原高清| 欧洲精品久久久av无码电影| 91麻豆国产精品91久久久| 久久青青草原精品国产软件| 一本伊大人香蕉久久网手机| 久久99国产精品尤物| 国产亚洲色婷婷久久99精品| AV无码久久久久不卡蜜桃| 久久婷婷国产剧情内射白浆| 伊人久久大香线蕉无码麻豆| 久久久久亚洲AV成人网| 久久人人爽人人澡人人高潮AV| 成人午夜精品久久久久久久小说| 94久久国产乱子伦精品免费 | 色婷婷综合久久久久中文| 欧美激情精品久久久久久久| 热RE99久久精品国产66热|