When you add your own opcodes one important thing to remember is uniqueness. Example, the "ret" opcode.
How to distinguish "ret 4" from "ret"?
The Map:
opCode["ret word"] := "C2"
opCode["ret"] := "C3"
Usage:
,"ret word",8 ;C20800
,"ret" ;C3
Here is an example that calls AHK Function from Asm.
Code: Select all
#Include opcodes.ahk
Msg_Box(p1,p2,p3){
Return &MsgBox(StrGet(p1),StrGet(p2),StrGet(p3))
}
; deBug := "`n"
pMB := CallbackCreate("Msg_Box")
flg := "ari iconi"
tit := "Call AHK Function With Asm Code"
txt := "AutoHotkey language bears some similarities to several other scripting languages but also has its own unique strengths and pitfalls."
Asm "push",&flg ;68408D3500
,"push",&tit ;68C08D3500
,"push",&txt ;6848123400
,"mov eax",pMB ;B8782A3700
,"call eax" ;FFD0
,"ret" ;C3
msgbox StrGet(DllCall(bAsm.Ptr)),"Return Code","4160 t1"
Then paste by "column mode" next to your opcodes, this will show any errors.
Under "Scripts and Functions" in the AHK forum there is a post called "Examples of Non-Standard GUIs (ActiveX, GDI, etc.)".
Maybe this next example could be a Non-Standard Gui.
It is a modal dialog box from a dialog box template in memory with ASM.
Code: Select all
#Include winapi.ahk
#Include opcodes.ahk
No_FocusDots(hWin,uMsg,wParam,lParam,uIdSubclass,dwRefData){
If(uMsg=WM_SETFOCUS)
Return
Return DefSubclassProc(hWin,uMsg,wParam,lParam)
}
Msg_Loop(hWin,uMsg,wParam,lParam){
Switch(uMsg){
Case WM_PAINT:
BeginPaint hWin,ps.Buf
DrawText hDC,winBody,ps.rcPaint,DT_CENTER
EndPaint hWin,ps.Buf
Case WM_INITDIALOG:
hDC := GetDC(hWin)
hBnd := GetDlgItem(hWin,ButtonID)
hFont := CreateFont(30,,,,800,,true,,,,,4,,"Times New Roman")
NoDots := CallbackCreate("No_FocusDots")
SelectObject hDC,hFont
SetTextColor hDC,0x00ffff ; Yellow
SetBkColor hDC,0x800000 ; Navy
SendMessage WM_SETICON,0,LoadImage(0,"crapper.ico",IMAGE_ICON),hWin
SendMessage WM_SETFONT,hFont,true,hBnd
SetWindowSubclass hBnd,NoDots,ButtonID
Case WM_CTLCOLORDLG:
Return Navy
Case WM_COMMAND:
If(wParam=IDCANCEL Or wParam=ButtonID){
DeleteObject hFont
ReleaseDC hWin,hDC
RemoveWindowSubclass hBnd,NoDots,ButtonID
EndDialog hWin,wParam
}
}
Return
}
; MAIN INLINE ASM CODE AHK 2.0-a104 U32
; Creates a modal dialog box from a dialog box template in memory.
; deBug := "`n"
global ps := new PAINTSTRUCT
global hDC := 0
global ButtonID := 69
global Navy := CreateSolidBrush(0x800000)
global winBody := "`nInLine Asm Dialog Box`nWith No Focus Dots On Button"
Tit := "AHK = Test ASM DialogBox"
Fnt := "MS Sans Serif"
Quit := "Q u i t"
DlgSize := 512
FntSize := 10
TitLen := StrLen(Tit)+1
FntLen := StrLen(Fnt)+1
QuitLen := StrLen(Quit)+1
bTit := BufferAlloc(TitLen)
bFnt := BufferAlloc(FntLen)
bQuit := BufferAlloc(QuitLen)
StrPut Tit,bTit,"cp0"
StrPut Fnt,bFnt,"cp0"
StrPut Quit,bQuit,"cp0"
style := WS_VISIBLE|WS_SYSMENU|WS_CAPTION|DS_CENTER|DS_SETFONT
xstyle := WS_EX_CLIENTEDGE
c1Style := WS_VISIBLE|WS_TABSTOP|BS_DEFPUSHBUTTON
c1XStyle := 0
x := 0,y := 0,w := 250,h := 180,ctlcnt := 1
cx1 := 180,cy1 := 140,cw1 := 50,ch1 := 25
pK32 := LoadLibrary("kernel32")
pU32 := LoadLibrary("user32")
pGlobalAlloc := GetProcAddress(pK32,"GlobalAlloc")
pGlobalFree := GetProcAddress(pK32,"GlobalFree")
pMultiByteToWideChar := GetProcAddress(pK32,"MultiByteToWideChar")
pDialogBoxIndirectParam := GetProcAddress(pU32,"DialogBoxIndirectParamW")
MsgLoop := CallbackCreate("Msg_Loop")
; SetUp DialogBox
Asm "push esi" ;56
,"push edi" ;57
,"push",DlgSize ;6800020000
,"push byte",GPTR ;6A40
,"mov eax",pGlobalAlloc ;B8D651FE76
,"call eax" ;FFD0
,"mov esi,eax" ;8BF0
,"mov edi,esi" ;8BFE
,"mov dword ptr[edi]",style ;C7074008C810
,"mov dword ptr[edi+4]",xstyle ;C7470400020000
,"mov word ptr[edi+8]",ctlcnt ;66C747080100
,"mov word ptr[edi+0A]",x ;66C7470A0000
,"mov word ptr[edi+0C]",y ;66C7470C0000
,"mov word ptr[edi+0E]",w ;66C7470EFA00
,"mov word ptr[edi+10]",h ;66C74710B400
,"add edi,byte",22 ;83C716
,"push byte",TitLen ;6A1F
,"push edi" ;57
,"push byte",-1 ;6AFF
,"push",bTit.Ptr ;6878F0B000
,"push byte",1 ;6A01
,"push byte",0 ;6A00
,"call",160 ;E893000000 jmp_MultiByteToWideChar
,"add edi,byte",TitLen*2 ;83C73E
,"mov word ptr[edi]",FntSize ;66C7070C00
,"add edi,byte",2 ;83C702
,"push byte",FntLen ;6A0E
,"push edi" ;57
,"push byte",-1 ;6AFF
,"push",bFnt.Ptr ;68085DB000
,"push byte",1 ;6A01
,"push byte",0 ;6A00
,"call",130 ;E875000000 jmp_MultiByteToWideChar
,"add edi,byte",FntLen*2 ;83C71C
; SetUp Button
; align_4
,"add edi,byte",3 ;83C703
,"and edi,byte",-4 ;83E7FC
,"mov dword ptr[edi]",c1Style ;C70701000110
,"mov dword ptr[edi+4]",c1XStyle ;C7470400000000
,"mov word ptr[edi+8]",cx1 ;66C747085A00
,"mov word ptr[edi+0A]",cy1 ;66C7470A3200
,"mov word ptr[edi+0C]",cw1 ;66C7470C3200
,"mov word ptr[edi+0E]",ch1 ;66C7470E0F00
,"mov word ptr[edi+10]",ButtonID ;66C747104500
,"mov word ptr[edi+12]",-1 ;66C74712FFFF
,"mov word ptr[edi+14]",Button ;66C747148000
,"add edi,byte",22 ;83C716
,"push byte",QuitLen ;6A05
,"push edi" ;57
,"push byte",-1 ;6AFF
,"push",bQuit.ptr ;68880AA800
,"push byte",1 ;6A01
,"push byte",0 ;6A00
,"call",44 ;E81F000000 jmp_MultiByteToWideChar
,"add edi,byte",QuitLen*2 ;83C70A
; align_2
,"add edi,byte",1 ;83C701
,"and edi,byte",-2 ;83E7FE
,"add edi,byte",2 ;83C702
; Call DialogBox
,"push byte",0 ;6A00
,"push",MsgLoop ;6818F1B000
,"push byte",0 ;6A00
,"push esi" ;56
,"push byte",0 ;6A00
,"mov eax",pDialogBoxIndirectParam ;B8F3D67676
,"call eax" ;FFD0
,"push eax" ;50
; Free Memory
,"push esi" ;56
,"mov eax",pGlobalFree ;B8485F8375
,"call eax" ;FFD0
,"pop eax" ;58
,"pop edi" ;5F
,"pop esi" ;5E
,"ret" ;C3
; Jmp_MultiByteToWideChar
,"jmp dword ptr[?]",&pMultiByteToWideChar ;FF25E4E4B200
; Call Asm
DllCall bAsm.Ptr
FreeLibrary pU32
FreeLibrary pK32
; msgbox A_LastError,"Asm Return","t1"