<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      翻譯:taowen

      用匯編訪問(wèn)COM對(duì)象

      Ernest Murphy ernie@surfree.com

      Revised Dec 26 2000 for inclusion as part of MASM32

      Revised July 10 2000 for the new form of coinvoke.

      Sample code for this article is available at ...\COM\examples\shortcut


      Abstract:

      原理:

      The COM (Component Object Model) is used by the Windows operation system in increasing ways. For example, the shell.dll uses COM to access some of its API methods. The IShellLink and IPersistFile interfaces of the shell32.dll will be demonstrated to create a shortcut shell link. A basic understanding of COM is assumed. The code sample included is MASM specific.

      COM(組件對(duì)象模型)越來(lái)越多地被Windows操作系統(tǒng)使用。例如,shell.dll使用COM來(lái)訪問(wèn)一些它自己的API函數(shù)。shell32.dll的IShellLink和IPersistFile接口將被用來(lái)演示如何創(chuàng)建一個(gè)快捷方式。COM的基本理解是需要的。包含的示例代碼是MASM專用的。


      Introduction:

      導(dǎo)言:

      COM may seem complicated with it's numerous details, but in use these complications disappear into simple function calls. The hardest part is understanding the data structures involved so you can define the interfaces. I apologize for all the C++ terminology used in here. While COM is implementation neutral, it borrows much terminology from C++ to define itself.

      COM由于其眾多的細(xì)節(jié)可能看上去復(fù)雜,但在實(shí)際使用中這些復(fù)雜因素消失于簡(jiǎn)單的函數(shù)調(diào)用之中。最困難的部分是理解其中用到的數(shù)據(jù)結(jié)構(gòu),知道了它你舊可以定義接口(interfaces)。我對(duì)在此處使用的C++術(shù)語(yǔ)表示抱歉。雖然COM被實(shí)現(xiàn)為中立的,但它從C++借用了許多術(shù)語(yǔ)來(lái)定義自身。

      In order to use the COM methods of some object, you must first instance or create that object from its coclass, then ask it to return you a pointer to it's interface. This process is performed by the API function CoCreateInstance. When you are done with the interface you call it's Release method, and COM and the coclass will take care of deleting the object and unloading the coclass.

      為了使用一些對(duì)象的COM函數(shù)(method),你必須首先根據(jù)它的coclass具像化(示例化)或者說(shuō)是創(chuàng)建這個(gè)對(duì)象。當(dāng)你用完了這個(gè)接口,你調(diào)用它的Release函數(shù),COM和coclass將會(huì)處理刪除對(duì)象和卸載coclass的任務(wù)。

      A COM object is referred to as the SERVER. The program that calls up a COM object so it may use it is referred to as the CLIENT.

      COM對(duì)象被稱為SERVER(服務(wù)器)。調(diào)用COM對(duì)象的程序被稱為CLIENT(客戶)


      Assessing COM Methods

      訪問(wèn)COM函數(shù)

      To use COM methods you need to know before hand what the interface looks like. Even if you "late bind" through an IDispatch interface, you still need to know what IDispatch looks like. A COM interface is just table of pointers to functions. Let's start with the IUnknown interface. If you were to create a component that simply exports the IUnknown interface, you have a fully functional COM object (albeit on the level of "Hello World"). IUnknown has the 3 basic methods of every interface, since all interfaces inherit from IUnknown. Keep in mind all an interface consists of is a structure of function pointers. For IUnknown, it looks like this:

      為了使用COM函數(shù)你需要事先知道接口(interface)的模樣。即使你通過(guò)一個(gè)IDispatch接口“動(dòng)態(tài)綁定”,你仍然需要知道IDispatch的模樣。一個(gè)COM接口就是一個(gè)函數(shù)指針的表格。讓我們從IUnknown接口開始。如果你要?jiǎng)?chuàng)建一個(gè)僅僅導(dǎo)出(export)IUnknown接口的組件,你將得到的是一個(gè)完善的COM對(duì)象(雖然僅是在“Hello World”的層次上)。每個(gè)接口有IUnknown的3個(gè)基本的函數(shù),因?yàn)樗械慕涌诙紡腎Unknown繼承而來(lái)。始終記得所有的接口是包含函數(shù)指針的結(jié)構(gòu)體(structure)。對(duì)于IUnknown來(lái)說(shuō),它就這模樣:

      IUnknown STRUCT DWORD 
      ; IUnknown methods 
      IUnknown_QueryInterface  QueryInterface_Pointer ? 
      IUnknown_AddRef   AddRef_Pointer ? 
      IUnknown_Release   Release_Pointer ?
      IUnknown ENDS
      

      That's it, just 12 bytes long. It holds 3 DWORD pointers to the procedures that actually implement the methods. It is the infamous "vtable" you may have heard of. The pointers are defined as such so we can have MASM do some type checking for us when compiling our calls. Since the vtable holds the addresses of functions, or pointers, these pointers are typedefed in our interface definition as such:

      這就是它,僅僅12字節(jié)長(zhǎng)。它保存著3個(gè)雙字大小(DWORD)的指針,指向?qū)嶋H實(shí)現(xiàn)的函數(shù)。它是你可能聽說(shuō)過(guò)的不著名的“vtable”。指針被如下定義,使得MASM可以在編譯我們的調(diào)用的時(shí)候?yàn)槟阕饕恍╊愋蜋z查。既然vtable保存了函數(shù)的地址,或者說(shuō)是指針,這些指針在我們的接口定義中被如此定義:

      QueryInterface_Pointer  typedef ptr QueryInterface_Proto
      AddRef_Pointer   typedef ptr AddRef_Proto 
      Release_Pointer   typedef ptr Release_Proto
      

      Finally, we define the function prototypes as follows:

      最后,我們?nèi)缦露x函數(shù)原型:

      QueryInterface_Proto  typedef PROTO :DWORD, :DWORD, :DWORD 
      AddRef_Pointer   typedef PROTO :DWORD 
      Release_Pointer   typedef PROTO :DWORD 
      

      In keeping with the MASM32 practice of "loose" type checking, function parameters are just defined as DWORDs. Lots of work to set things up, but it does keeps lots of errors confined to compile time, not run time. In practice, we will wrap up these interface definitions in include files and keep them from cluttering up the source code.

      為了保持MASM32的“松散”類型檢查的原則,函數(shù)參數(shù)只是被定義為DWORD。為了把東西搞定要作不少的工作,但它確實(shí)把許多錯(cuò)誤限定在了編譯期,而不是在運(yùn)行時(shí)。原則上,我們要把這些接口定義包裝在包含文件中,避免他們?cè)谠创a中被搞混亂了。

      One rather big compilation on defining an interface: MASM cannot resolve forward references like this, so we have to define them backwards, by defining the function prototype typedefs first, and the interface table last. The include files for the example program later on defines the interfaces this way.

      定義一個(gè)接口的大問(wèn)題時(shí):MASM不能決議(resolve)像這樣的前向參考,因而我們必須在后面定義他們,先定義函數(shù)原型后定義接口表(interface table)。后面的示例程序的包含文件用這種方式定義接口。

      To actually use an interface, you need a pointer to it.

      為了實(shí)際使用一個(gè)接口,你需要一個(gè)指向它的指針。

      The CoCreateInstance API can be used to return us this indirect pointer to an interface structure. It is one level removed from the vtable itself, and actually points to the "object" that holds the interface. The final structure looks like this: CoCreateInstance

      API可以被用來(lái)返回間接指向一個(gè)接口結(jié)構(gòu)的指針。它從vtable本身移開了一個(gè)層次,而實(shí)際是指向一個(gè)“對(duì)象”,該對(duì)象保存了接口。最終的結(jié)構(gòu)就是這模樣:

      There is a lot of indirection using this structure, it can drive you batty trying to write code to properly reference and de-reference these elements. Macros to simplify this task will be defined.

      使用這個(gè)結(jié)構(gòu)其中有很多間接,如果你嘗試著寫代碼來(lái)恰當(dāng)?shù)囊茫╮eference)和取消引用(de-reference)這些元素,它會(huì)使你抓狂。將定義一些宏來(lái)簡(jiǎn)化這樣的工作。

      When the client makes a call to the COM library to create a COM object, it passes in the address where it wants the object pointer to be placed. This initial pointer is generically referred to as "ppv," from the C++ speak "pointer to pointer to (void)," where (void) means an unspecified type. It holds the address of another pointer ("pv"), and this pointer refers to a whole table of pointers, one table entry for each function of the interface.

      當(dāng)用戶調(diào)用COM庫(kù)來(lái)創(chuàng)建一個(gè)COM對(duì)象,它傳遞過(guò)去一個(gè)地址,在那保存對(duì)象的指針。這個(gè)最初的指針一般被稱為“ppv”,從C++的觀點(diǎn)來(lái)說(shuō)就是“指向 指向void類型的指針的指針”,其中void意為未指定的類型。它保存了另外一個(gè)指針(“pv”)的地址,而那個(gè)指針指向一整個(gè)指針表格,對(duì)應(yīng)一個(gè)接口中的函數(shù)有一個(gè)表格項(xiàng)。

      For example, say we used CoCreateInstance and successfully got an interface pointer ppv, and wanted to see if it supports some other interface. We can call its QueryInterface method and request a new ppv (ppv2, pointer to an Interface) to the other interface (pIID, pointer to a Interface Identifying GUID) we are interested in. In C, QueryInterface has a prototype that would look like so:

      例如,我們用CoCreateInstance成功地獲得一個(gè)接口指針ppv,并且想要看它是否支持其他地一些接口。我們可以調(diào)用它地QueryInterface函數(shù)來(lái)請(qǐng)求一個(gè)新的指向其他我們感興趣的接口(pIID,接口指針標(biāo)識(shí)GUID)的ppv(ppv2,一個(gè)接口的指針)。用C,QueryInterface有一個(gè)如下的原型:

      (HRESULT) SomeObject::QueryInterface (this:pObject, IID:pGUID, ppv2:pInterface)
      

      Such a call would look like this:

      這么一個(gè)調(diào)用要這樣作:

      ; get pointer to the object 
      mov eax, ppv 
      ; and use it to find the interface structure
      mov edx, [eax] 
      ; push the function parameters onto the stack
      push OFFSET ppv2
      push OFFSET IID_ISomeOtherInterface
      push dword ppv
      ; and then call that method 
      call dword ptr [eax + 0]
      

      This may be accomplished using the built-in MASM 'invoke' macro as such:

      這個(gè)可以使用MASM內(nèi)建的“invoke”宏來(lái)完成,就像這樣:

      ; get pointer to the object 
      mov eax, ppv 
      ; and use it to find the interface structure
      mov edx, [eax] 
      ; and then call that method 
      invoke (IUnknown PTR [edx]).IUnknown_QueryInterface, ppv,
          ADDR IID_SomeOtherInterface, ADDR ppv_new
      

      I hope you find this as wonderfully simple as I do.

      我希望你能和我一樣發(fā)現(xiàn)這些相當(dāng)簡(jiǎn)單。

      Note we must pass in the pointer we used, this lets the interface know which object (literally "this" object) we are using.

      注意我們必須傳遞我們使用的指針,這個(gè)使得接口知道哪個(gè)對(duì)象(嚴(yán)格的說(shuō),“這個(gè)”對(duì)象)我們正在使用。

      Note the register must be type cast (IUnknown PTR [edx]). This lets the compiler know what structure to use to get the correct offset in the vtable for the .QueryInterface function (in this case it means an offset of zero from [edx]). Actually, the information contained by the interface name and function name called disappear at compile time, all that is left is a numeric offset from an as of yet value unspecified pointer.

      注意寄存器必須轉(zhuǎn)換類型(IUnknown PTR [edx])。這個(gè)讓編譯器知道使用什么結(jié)構(gòu)在QueryInterface函數(shù)的vtable中來(lái)獲得正確的偏移位置(在這例中,它意為從[edx]開始的0偏移位置)。實(shí)際上,由接口名和函數(shù)名所包含的信息在編譯的時(shí)候就消失了,所有剩下的就是從一個(gè)還沒(méi)有指定值的指針開始的一個(gè)數(shù)字偏移位置。

      One more semi-obscure point. Notice I changed the interface method name from simply "QueryInterface" to "IUnknown_QueryInterface". This is a bit of name decoration I've found necessary. When you get to larger COM projects with many similar interfaces you will run into a problem, that is different interfaces with identical method names. This is quite valid, in fact it's called polymorphism, but can confuse the compiler a bit.

      另一個(gè)有些晦澀不明的地方。注意我把接口函數(shù)名從簡(jiǎn)單的“QueryInterface”改變?yōu)椤癐Unknown_QueryInterface”。這是我發(fā)現(xiàn)必要的一點(diǎn)名稱裝飾。當(dāng)你要進(jìn)行一個(gè)大一點(diǎn)的COM工程,它有許多可能使你遇到麻煩的很相象的接口。也就是不同的接口有相同的函數(shù)名。這個(gè)是絕對(duì)有效的,實(shí)際上它被稱為多態(tài),但可能會(huì)使得編譯器不明白。

      Without this name decoration scheme things will be safe until you have two different interfaces with identical method names but different parameters to that method. This is more common then you might first think, but just consider how many interfaces might have a PRINT method.

      不加入名稱裝飾,事情在你遇到這么兩個(gè)不同接口之前事情還是安全,它們包含有相同函數(shù)名但參數(shù)又是不一樣的函數(shù)。這種情況比你一想之下的還要常見(jiàn),只要考慮可能會(huì)有多少個(gè)接口有PRINT函數(shù)。


      The coinvoke Macro

      coinvoke宏

      We can simplify a COM invoke further with a macro. This coinvoke macro is part of the oaidl.inc file.

      我們可以通過(guò)宏來(lái)進(jìn)一步簡(jiǎn)化COM的調(diào)用。這個(gè)coinvoke宏是oaidl.inc文件的一部分。

      ;---------------------------------------------------------------------
      ; coinvoke MACRO 
      ;
      ; invokes an arbitrary COM interface 
      ;
      ; revised 12/29/00 to check for edx as a param and force compilation error
      ;                   (thanks to Andy Car for a how-to suggestion)
      ; revised 7/18/00 to pass pointer in edx (not eax) to avoid confusion with
      ;   parmas passed with ADDR  (Jeremy Collake's excellent suggestion)
      ; revised 5/4/00 for member function name decoration
      ; see http://ourworld.compuserve.com/homepages/ernies_world/coinvoke.htm
      ;
      ; pInterface    pointer to a specific interface instance
      ; Interface     the Interface's struct typedef
      ; Function      which function or method of the interface to perform
      ; args          all required arguments 
      ;                   (type, kind and count determined by the function)
      ;
      coinvoke MACRO pInterface:REQ, Interface:REQ, Function:REQ, args:VARARG
          LOCAL istatement, arg
          FOR arg,      ;; run thru args to see if edx is lurking in there
              IFIDNI <&arg>, 
                  .ERR 
              ENDIF
          ENDM
          istatement CATSTR ,<_>,<&Function, pInterface>
          IFNB      ;; add the list of parameter arguments if any
              istatement CATSTR istatement, <, >, <&args> 
          ENDIF 
          mov edx, pInterface
          mov edx, [edx]
          istatement
      ENDM
      ;---------------------------------------------------------------------
      

      Thus, the same QueryInterface method as before can be invoked in a single line:

      因此,和之前一樣的QueryInterface函數(shù)可以用一行來(lái)調(diào)用:

      coinvoke ppv ,IUnknown, QueryInterface, ADDR IID_SomeOtherInterface, ADDR ppnew
      

      Note that now the name decoration is done for us by the macro.

      注意同樣的名字裝飾由宏來(lái)替我們完成了。

      The only 'gotcha' (well, the most obvious) is that no parameters to a COM call should be passed in edx as this register is used to handle 'this' the object reference. Using edx as a parameter will generate a compile error.

      唯一的已經(jīng)找出的麻煩(呃,最明顯的)是調(diào)用COM的參數(shù)中不能有一個(gè)是通過(guò)edx傳遞的,因?yàn)檫@個(gè)寄存器被用來(lái)處理指向?qū)ο蟮膖his。使用edx作為一個(gè)參數(shù)會(huì)產(chǎn)生一個(gè)編譯錯(cuò)誤。


      Using IShellFile and IPersistFile from shell32.dll

      使用shell32.dll中IShellFile和IPersistFile

      The shell32.dll provides a simple. easy way to make shell links (shortcuts). However, it uses a COM interface to provide this service. The sample below is based on the MSDN "Shell Links" section for "Internet Tools and Technologies."

      shell32.dll提供了一個(gè)簡(jiǎn)單容易的辦法來(lái)創(chuàng)建快捷方式。然而,它使用COM接口來(lái)提供這項(xiàng)服務(wù)。下面的例子是基于MSDN的“Internet Tools and Technologies”的“Shell Links”部分。

      This may be a strange place to find documentation, but there it is.

      這可能是一個(gè)找到文檔的奇怪的地方,但它就在那。

      The "Shell Links" article may be found at: http://msdn.microsoft.com/library/psdk/shellcc/shell/Shortcut.htm

      “Shell Links”的文章可以在http://msdn.microsoft.com/library/psdk/shellcc/shell/Shortcut.htm找到。

      For this tutorial we will access the following members of the IShellLink and the IPersistFile interfaces. Note every interface includes a "ppi" interface parameter, this is the interface that we calling to (it is the THIS parameter). (The following interface information is a copy of information published by Microsoft)

      在本教程中,我們將訪問(wèn)IShellLink和IPersistFile這兩個(gè)接口的一下成員。注意每個(gè)接口都包括一個(gè)“ppi”接口參數(shù),這個(gè)是我們正在調(diào)用的接口的指針(它是THIS參數(shù))。(下面的接口信息是由微軟發(fā)布的信息的復(fù)制)

      IShellLink::QueryInterface, ppi, ADDR riid, ADDR ppv 
        * riid: The identifier of the interface requested. To get access to the 
        * ppv: The pointer to the variable that receives the interface. 
        Description: Checks if the object also supports the requested interface. If so, 
        signs the ppv pointer with the interface's pointer. 
      
      IShellLink::Release, ppi Description: Decrements the reference count on the IShellLink interface.
      IShellLink:: SetPath, ppi, ADDR szFile * pszFile: A pointer to a text buffer containing the new path for the shell link object. Description: Defines where the file the shell link points to.
      IShellLink::SetIconLocation, ppi, ADDR szIconPath, iIcon * pszIconPath: A pointer to a text buffer containing the new icon path. * iIcon: An index to the icon. This index is zero based. Description: Sets which icon the shelllink will use.
      IPersistFile::Save, ppi, ADDR szFileName, fRemember * pszFileName: Points to a zero-terminated string containing the absolute path of the file to which the object should be saved. * fRemember: Indicates whether the pszFileName parameter is to be used as the current working file. If TRUE, pszFileName becomes the current file and the object should clear its dirty flag after the save. If FALSE, this save operation is a "Save A Copy As ..." operation. In this case, the current file is unchanged and the object should not clear its dirty flag. If pszFileName is NULL, the implementation should ignore the fRemember flag. Description: Perform a save operation for the ShellLink object, or saves the shell link are creating.
      IPersistFile::Release, ppi Description: Decrements the reference count on the IPersistFile interface.

      These interfaces contain many many more methods (see the full interface definitions in the code below), but we only need concentrate on those we will actually be using.

      這些接口包含比這更多的函數(shù)(參考下面代碼中的接口定義),但我們僅僅需要集中注意我們將實(shí)際使用的那幾個(gè)。

      A shell link is the MS-speak name for a shortcut icon. The information contained in a link (.lnk) file is:

      shell link是快捷方式的微軟說(shuō)法。包含在一個(gè)link(.lnk)文件中的信息有:

      • 1 - The file path and name of the program to shell.
      • 2 - Where to obtain the icon to display for the shortcut (usually from the executable itself), and which icon in that file to use. We will use the first icon in the file
      • 3 - A file path and name where the shortcut should be stored.
      • 1 - 指向的程序的路徑和名字。
      • 2 - 快捷方式顯示的圖標(biāo)的路徑(通常是執(zhí)行文件本身),以及那是文件中的哪個(gè)圖標(biāo)。我們將使用文件的第一個(gè)圖標(biāo)。
      • 3 - 快捷方式應(yīng)該被存放在的文件路徑和名字。

      The use of these interfaces is simple and straightforward. It goes like this:

      這些接口的用法是相當(dāng)簡(jiǎn)單明了的。整個(gè)過(guò)程是這樣:

      Call CoCreateInstance CLSID_ShellLink for a IID_IShellLink interface

      調(diào)用CoCreateInstance CLSID_ShellLink得到一個(gè)IID_IShellLink接口

      QueryInterface IShellLink for an IID_IPersistFile interface.

      QueryInterface IShellLink得到IID_IPersistFile接口。

      Call IShellLink.SetPath to specify where the shortcut target is

      調(diào)用IShellLink.SetPath 來(lái)指定快捷方式指向的目標(biāo)。

      Call IShellLink.SetIconLocation to specify which icon to use

      調(diào)用IShellLink.SetIconLocation來(lái)指定使用哪個(gè)圖標(biāo)。

      Call IPersistFile.Save to save our new shortcut .lnk file.

      調(diào)用IPersistFile.Save來(lái)保存我們的新的快捷方式.lnk文件。

      finally,

      最后

      Call IPersistFile.Release

      調(diào)用IPersistFile.Release

      Call IShellLink.Release

      調(diào)用IShellLink.Release

      This releases our hold on these interfaces, which will automatically lead to the dll that supplied them being unloaded. Again, the hard part in this application was finding documentation. What finally found broke the search open was using Visual Studio "Search in Files" to find "IShellLink" and " IPersistFile" in the /include area of MSVC. This lead me to various .h files, from which I hand translated the interfaces from C to MASM.

      這樣作釋放了我們保存的接口。而這將自動(dòng)卸載提供他們的dll。此外,寫程序中最困那的部分是查找文檔。最終打破尋找僵局的是用Visual Studio的“在文件中查找”在MSVC的include目錄中查找“IShellLink”和“IPersistFile”。這把我引向了好幾個(gè).h文件,在那我手工把接口定義從C翻譯為MASM。

      Another handy tool I could have used is the command line app "FindGUID.exe," which looks through the registry for a specific interface name or coclass, or will output a list of every class and interface with their associated GUIDs.

      另一個(gè)我使用的便利的工具是命令行程序“FindGUID.exe”,它在整個(gè)注冊(cè)表中查找一個(gè)指定的接口名或coclass,或者輸出每個(gè)類和接口以及他們所關(guān)聯(lián)的GUID。

      Finally, the OLEView.exe application will let you browse the registry type libraries and mine them for information. However, these tools come with MSVC and are proprietary.

      最后,OLEView.exe程序讓你瀏覽注冊(cè)表的類型庫(kù),從中挖掘出信息。然而,這個(gè)工具是隨MSVC一同發(fā)售的,是有版權(quán)的。

      Take care when defining an interface. Missing vtable methods lead to strange results. Essentially COM calls, on one level, amount to "perform function (number)" calls. Leave a method out of the vtable definition and you call the wrong interface. The original IShellLink interface definition I used from a inc file I downloaded had a missing function. The calls I made generated a "SUCCEEDED" hResult, but in some cases would not properly clean the stack (since my push count did not match the invoked function's pop count), thus lead to a GPF as I exited a procedure. Keep this in mind if you ever get similar "weird" results.

      當(dāng)定義一個(gè)接口的時(shí)候要小心。缺失vtable的函數(shù)導(dǎo)致奇怪的結(jié)果。

      本質(zhì)上COM調(diào)用,從一個(gè)層面上來(lái)說(shuō),相當(dāng)于“執(zhí)行 function(number)”。把一個(gè)函數(shù)缺失在vtable的定義之外導(dǎo)致你調(diào)用了錯(cuò)誤的接口。我使用的IShellLink接口的最初的定義是來(lái)自于一個(gè)下載的inc文件,它少了一個(gè)函數(shù)。我作出的調(diào)用產(chǎn)生了“SUCCEEDED”的hResult,但在某些情況下可能不能正常的清棧(因?yàn)槲业膒ush的次數(shù)和調(diào)用的函數(shù)的pop的次數(shù)不相匹配),因而在我退出一個(gè)函數(shù)的時(shí)候?qū)е翯PF。牢記這一點(diǎn),當(dāng)你得到類似的“奇異”結(jié)果的時(shí)候。


      MakeLink.asm, a demonstration of COM

      MakeLink.asm,com的一個(gè)演示

      This program does very little, as a good tutorial program should. When run, it creates a shortcut to itself, in the same directory. It can be amusing to run from file explorer and watch the shortcut appear. Then you can try the shortcut and watch it's creation time change.

      這個(gè)程序沒(méi)有干什么太多的事情,就像一個(gè)好的教程中的程序應(yīng)該作的。運(yùn)行之后,它在同一個(gè)目錄中創(chuàng)建了一個(gè)指向自身的快捷方式。在文件管理器中運(yùn)行并觀察快捷方式的產(chǎn)生可能會(huì)很有趣。然后你可以試一試快捷方式并看到它的創(chuàng)建時(shí)間被改變了。

      The shell link tutorial code is in ...\COM\examples\shortcut. It begins with some "hack code" to get the full file name path of the executable, and also makes a string with the same path that changes the file to "Shortcut To ShellLink.lnk" These strings are passed to the shell link interface, and it is saved (or persisted in COM-speak).

      快捷方式的示例代碼位于...\COM\examples\shortcut。它由一些為了獲得可執(zhí)行文件的文件名的完整路徑的“hack code”開始,而且用相同的路徑創(chuàng)建了一個(gè)字符串。它把文件改變?yōu)?Shortcut To ShellLink.lnk"。這幾個(gè)字符串被傳遞給shell link接口,而且它被保存了(用COM的語(yǔ)言,被持久化了)。

      The CoCreateLink procedure used to actually perform the COM methods and perform this link creation has been kept as general as possible, and may have reuse possibilities in other applications.

      用來(lái)實(shí)際執(zhí)行COM函數(shù)和實(shí)現(xiàn)快捷方式創(chuàng)建的CoCreateLink函數(shù)被設(shè)計(jì)為盡可能的通用,因而可能在其他程序中有重用的可能。

      This program is similar to earlier published tutorial, but has been edited for some additional clarity. The interfaces are defined in a separate include file to reduce clutter. It may be built in MASM32 by using the ...\COM\bin\BLDDLL.BAT file supplied.

      這個(gè)程序和早先發(fā)布的教程很相象,但為了更加清晰而重新進(jìn)行了編輯。為了避免混亂接口在獨(dú)立的包含文件中定義。它可以通過(guò)使用提供的...\com\bin\bldll.bat文件來(lái)建立。

      Additional note: Iczelion has quite a useful file in his tutorials named resource.h. It is quite useful when using rc.exe to compile resource files. I use it so much I have moved it to my /masm32/include/ folder. You need to either move your copy there, or change the path in the rsrc.rc file to build it properly.

      附加的說(shuō)明:Iczelion在它的教程中有一個(gè)名為resource.h的相當(dāng)有用的文件。在使用rc.exe來(lái)編譯資源文件的時(shí)候,這個(gè)相當(dāng)有用。我用它太頻繁了以至于我把它移動(dòng)到了我的/masm32/include文件夾。你需要要么把你的那份拷貝移到那兒,或者改變r(jià)src.rc文件中的路徑使得能夠正常的建立。


      Bibliography:

      參考書目:

      "Inside COM, Microsoft's Component Object Model" Dale Rogerson Copyright 1997,

      Paperback - 376 pages CD-ROM edition

      Microsoft Press; ISBN: 1572313498

      (THE book for understanding how COM works on a fundamental level. Uses C++ code to illustrate basic concepts as it builds simple fully functional COM object)

      "Automation Programmer's Reference : Using ActiveX Technology to Create

      Programmable Applications" (no author listed)

      Copyright 1997,

      Paperback - 450 pages

      Microsoft Press; ISBN: 1572315849

      (This book has been available online on MSDN in the past, but it is cheap enough for those of you who prefer real books you can hold in your hand. Defines the practical interfaces and functions that the automation libraries provide you, but is more of a reference book then a "user's guide")

      Microsoft Developers Network

      http://msdn.microsoft.com/

      "Professional Visual C++ 5 ActiveX/Com Control Programming" Sing Li and Panos Economopoulos

      Copyright April 1997,

      Paperback - 500 pages (no CD Rom, files available online)

      Wrox Press Inc; ISBN: 1861000375

      (Excellent description of activeX control and control site interfaces. A recent review of this book on Amazon.com stated "These guys are the type that want to rewrite the world's entire software base in assembler." Need I say more?)

      "sean's inconsequential homepage" http://ript.net/~spec/

      Various hardcore articles on low-level COM and ATL techniques. Coded in C++

      "Using COM in Assembly Language" Bill Tyler

      http://thunder.prohosting.com/~asm1/

      Assembly Language Journal, Apr-June 99


      代碼

      MakeLink.asm

      ;---------------------------------------------------------------------
      ; MakeLink.asm ActiveX simple client to demonstrate basic concepts
      ;               written & (c) copyright April 5, 2000 by Ernest Murphy
      ;
      ;               contact the author at ernie@surfree.com
      ;
      ;               may be reused for any educational or
      ;               non-commercial application without further license
      ;---------------------------------------------------------------------
      .386
      .model flat, stdcall
      option casemap:none
      
      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\ole32.inc
      include \masm32\com\include\oaidl.inc
      include \masm32\com\include\shlobj.inc
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\ole32.lib
      ;---------------------------------------------------------------------
      CoCreateLink      PROTO :DWORD, :DWORD
      MakeMessage MACRO Text:REQ
          ; macro to display a message box
          ; the text to display is kept local to
          ; this routine for ease of use
          LOCAL lbl
          LOCAL sztext
          jmp lbl
      sztext:  
          db Text,0
      lbl:
          invoke MessageBox,NULL,sztext,ADDR szAppName,MB_OK
          ENDM
        ; IPersistFile Interface 
        IPersistFile            STRUCT DWORD
             IPersistFile_QueryInterface       comethod3       ?
             IPersistFile_AddRef               comethod1       ?
             IPersistFile_Release              comethod1       ?
             IPersistFile_GetClassID           comethod2       ?
             IPersistFile_IsDirty              comethod1       ?
             IPersistFile_Load                 comethod3       ?
             IPersistFile_Save                 comethod3       ?
             IPersistFile_SaveCompleted        comethod2       ?
             IPersistFile_GetCurFile           comethod2       ?
       IPersistFile            ENDS
      ;---------------------------------------------------------------------
      .data
      szAppName         BYTE     "Shell Link Maker", 0
      szLinkName        BYTE     "Shortcut to MakeLink.lnk", 0
      szBKSlash   BYTE   "\", 0
      hInstance         HINSTANCE   ?
      Pos               DWORD       ?
      szBuffer1   BYTE   MAX_PATH DUP(?)
      szBuffer2   BYTE   MAX_PATH DUP(?)
      ;---------------------------------------------------------------------
      .code
      start:
      ;---------------------------------------------------------------------
      ;  this bracketed code is just a 'quick hack'
      ;  to replace the filename from the filepathname
      ;  with the 'Shortcut to' title
      ;
          invoke GetModuleHandle, NULL
          mov hInstance, eax
          invoke GetModuleFileName, NULL, ADDR szBuffer1, MAX_PATH
          invoke lstrcpy, ADDR szBuffer2, ADDR szBuffer1
          ; Find the last backslash '\' and change it to zero
          mov edx, OFFSET szBuffer2
          mov ecx, edx
          .REPEAT
              mov al, BYTE PTR [edx]
              .IF al == 92 ; "\"
                  mov ecx, edx
              .ENDIF
              inc edx
          .UNTIL  al == 0
          mov BYTE PTR [ecx+1], 0   
          invoke lstrcpy, ADDR szBuffer2, ADDR szLinkName
      ;---------------------------------------------------------------------
      ; here is where we call the proc with the COM methods
          invoke CoInitialize, NULL
          MakeMessage "Let's try our Createlink."
          invoke CoCreateLink, ADDR szBuffer1, ADDR szBuffer2
          MakeMessage "That's all folks !!!"
          invoke CoUninitialize
      invoke ExitProcess, NULL
      ;---------------------------------------------------------------------
      CoCreateLink PROC pszPathObj:DWORD, pszPathLink:DWORD
       ; CreateLink - uses the shell's IShellLink and IPersistFile interfaces 
       ;   to create and store a shortcut to the specified object. 
       ; Returns the hresult of calling the member functions of the interfaces. 
       ; pszPathObj - address of a buffer containing the path of the object. 
       ; pszPathLink - address of a buffer containing the path where the 
       ;   shell link is to be stored. 
       ; addapted from MSDN article "Shell Links"
       ;  deleted useless "description" method
       ;  added set icon location method
          LOCAL   pwsz    :DWORD         
          LOCAL   psl     :DWORD         
          LOCAL   ppf     :DWORD       
          LOCAL   hResult :DWORD       
          LOCAL   hHeap   :DWORD       
      .data
      CLSID_ShellLink     GUID       sCLSID_ShellLink
      IID_IShellLink      GUID       sIID_IShellLink
      IID_IPersistFile    GUID       {00000010bH, 00000H, 00000H, \ 
                                     {0C0H, 000H, 000H, 000H, 000H, 000H, 000H, 046H}}
      .code
          ; first, get some heap for a wide buffer
          invoke GetProcessHeap
          mov hHeap, eax
          invoke HeapAlloc, hHeap, NULL, MAX_PATH * 2
          mov pwsz, eax
          ; Get a pointer to the IShellLink interface. 
          invoke CoCreateInstance, ADDR CLSID_ShellLink, NULL, 
                                   CLSCTX_INPROC_SERVER, 
                                   ADDR IID_IShellLink, ADDR psl
          mov hResult, eax
          test eax, eax
          .IF SUCCEEDED 
              ; Query IShellLink for the IPersistFile 
              ; interface for saving the shortcut
              coinvoke psl, IShellLink, QueryInterface, ADDR IID_IPersistFile, ADDR ppf
              mov hResult, eax
              test eax, eax
              .IF SUCCEEDED 
                  ; Set the path to the shortcut target 
                  coinvoke psl, IShellLink, SetPath, pszPathObj
                  mov hResult, eax
                  ; add the  description, use first icon found
                  coinvoke psl, IShellLink, SetIconLocation, pszPathObj, 0 
                  mov hResult, eax
                  ; change string to Unicode. 
                  ; (COM typically expects Unicode strings)
                  invoke MultiByteToWideChar, CP_ACP, 0, pszPathLink, 
                                              -1, pwsz, MAX_PATH
                  ; Save the link by calling IPersistFile::Save
        coinvoke ppf, IPersistFile, Save, pwsz, TRUE
                  mov eax, hResult
                  ; release the IPersistFile ppf pointer
                  coinvoke ppf, IPersistFile, Release
                  mov hResult, eax
              .ENDIF
              ; release the IShellLink psl pointer
              coinvoke psl, IShellLink, Release
              mov hResult, eax
          .ENDIF
          ; free our heap space
          invoke HeapFree, hHeap, NULL, pwsz
          mov eax, hResult    ; since we reuse this variable over and over,
                              ;  it contains the last operations result
          ret
      CoCreateLink ENDP
      ;---------------------------------------------------------------------
      end start 
      

      rsrc.rc

      // resource.h may be found in Iczelion's tut #10-1
      // it is well worth moving to your /masm32/include/ folder
      #include "\masm32\include\resource.h"
      #define IDC_ICON1              1001
      #define IDC_ICON2              1002
      
      IDI_ICON1     ICON   MOVEABLE PURE LOADONCALL DISCARDABLE "PLANE.ICO"
      IDI_ICON2     ICON   MOVEABLE PURE LOADONCALL DISCARDABLE "TRFFC14.ICO"
      
      posted on 2004-05-24 19:05  taowen  閱讀(2002)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 骚虎视频在线观看| 日本熟妇浓毛| 亚洲欧美色一区二区三区| 免费无码高H视频在线观看| 亚洲精品第一区二区三区| 午夜丰满少妇性开放视频| 久久婷婷成人综合色综合| 在线观看潮喷失禁大喷水无码| 国产女人水真多18毛片18精品| 熟女视频一区二区三区嫩草| 亚洲色一色噜一噜噜噜| 国产超碰无码最新上传| 人人入人人爱| 国产资源精品中文字幕| 久久精品亚洲精品国产色婷| 日本韩国日韩少妇熟女少妇| 国产一区二区三区在线观看免费| 久久er99热精品一区二区| 欧美精品一区二区三区中文字幕 | 白嫩少妇无套内谢视频| 亚洲欧美综合一区二区三区| 久青草国产综合视频在线| 国产亚洲一区二区三区成人| 四虎影院176| 日本免费一区二区三区日本| 亚洲第一香蕉视频啪啪爽| 狠狠躁夜夜躁人人爽天天5| 国产自拍一区二区三区在线| 在线观看潮喷失禁大喷水无码| 高清国产av一区二区三区| 汝阳县| 亚洲综合一区二区三区不卡| av在线播放国产一区| 野外做受三级视频| 九九热在线视频只有精品| 亚洲日韩AV秘 无码一区二区| 中文字幕av无码免费一区| 日本深夜福利在线观看| 国产999久久高清免费观看| 国产精品日韩深夜福利久久| 无遮挡aaaaa大片免费看|