MakeLink.asm, a demonstration of COM
MakeLink.asm,com的一個示範
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.
這個程式沒有幹什麼太多的事情,就像一個好的教程中的程式應該作的。運作之後,它在同一個目錄中建立了一個指向自身的快捷方式。在檔案管理器中運作并觀察快捷方式的産生可能會很有趣。然後你可以試一試快捷方式并看到它的建立時間被改變了。
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。它由一些為了獲得可執行檔案的檔案名的完整路徑的“hack code”開始,而且用相同的路徑建立了一個字元串。它把檔案改變為"Shortcut To ShellLink.lnk"。這幾個字元串被傳遞給shell link接口,而且它被儲存了(用COM的語言,被持久化了)。
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.
用來實際執行COM函數和實作快捷方式建立的CoCreateLink函數被設計為盡可能的通用,因而可能在其他程式中有重用的可能。
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.
這個程式和早先釋出的教程很相象,但為了更加清晰而重新進行了編輯。為了避免混亂接口在獨立的包含檔案中定義。它可以通過使用提供的.../com/bin/bldll.bat檔案來建立。
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.
附加的說明:Iczelion在它的教程中有一個名為resource.h的相當有用的檔案。在使用rc.exe來編譯資源檔案的時候,這個相當有用。我用它太頻繁了以至于我把它移動到了我的/masm32/include檔案夾。你需要要麼把你的那份拷貝移到那兒,或者改變rsrc.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
代碼
*purpleendurer注:
要連結成功,需要将/masm32/com/include/shlobj.inc中的
;---------------------------------------------------------------------
; MakeLink.asm ActiveX simple client to demonstrate basic concepts
; written & (c) copyright April 5, 2000 by Ernest Murphy
;
; contact the author at [email protected]
;
; 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"