DynaCall Parameter position adjustment

Ask for help, how to use AHK_H, etc.
arcticir
Posts: 694
Joined: 17 Nov 2013, 11:32

DynaCall Parameter position adjustment

07 Sep 2017, 09:25

I encountered a problem when wrapping D2D1, this function can not adjust the parameter position.

Its DllCall way is this: (where this.ptr is a fixed constant.)

Code: Select all

         CreateSolidColorBrush(color, brushProperties, Byref solidColorBrush)
         {
                 return DllCall (NumGet (this.vt + 8 * A_PtrSize), "ptr", this.ptr, "ptr", color, "ptr", brushProperties, "ptr *", solidColorBrush)
         }
But I wrap it like this, both ways are invalid:

Code: Select all

this.CreateSolidColorBrush:=DynaCall(NumGet(vt+8*A_PtrSize),["tttt*",2],this.ptr)
this.CreateSolidColorBrush:=DynaCall(NumGet(vt+8*A_PtrSize),"tttt*",this.ptr)
normal:		oRenderTarget.CreateSolidColorBrush[pRenderTarget,&tD2D1_COLOR_F,&tD2D1_BRUSH_PROPERTIES,pBrush]
error:		oRenderTarget.CreateSolidColorBrush[&tD2D1_COLOR_F,&tD2D1_BRUSH_PROPERTIES,pBrush]

Code: Select all


global oD2D1Factory     ; Direct2d 对象
      ,sizeX := 500                ; 窗口宽度
          ,sizeY := 500                ; 窗口高度
          ,hGui                                ; 窗口句柄
DllCall("LoadLibrary",str,"d2d1.dll")

DllCall("LoadLibrary",str,"ole32.dll")

; 创建 Direct2d 对象
id := _D2D1CreateFactoryObject()

oD2D1Factory := new ID2D1Factory(id)


; 创建窗口

gui:=GuiCreate()
hGui:=gui.hwnd
gui.show("w" sizex " h" sizey)

sizeX := sizeY := 500

; 接收 WM_PAINT 窗口消息

OnMessage(0xF,"_Direct2D_PAINT")
OnMessage(0x14,"_WM_ERASEBKGND")

SendMessage_(gui.hwnd,0xf,0,0) ;,0xF,,,,ahk_id %hGui%
return

GuiClose:
ExitApp

_WM_ERASEBKGND()
{
        return 0
}

; 重绘函数
_Direct2D_PAINT()
{

        ; 定义窗口绘制对象
        _struct(tD2D1_RENDER_TARGET_PROPERTIES,"uint;uint;uint;float;float;uint;uint")
        _struct(tD2D1_HWND_RENDER_TARGET_PROPERTIES,"uint;uint;uint;uint",hGui,sizeX,sizeY,0)
        oD2D1Factory.CreateHwndRenderTarget(&tD2D1_RENDER_TARGET_PROPERTIES,&tD2D1_HWND_RENDER_TARGET_PROPERTIES,pRenderTarget)
        oRenderTarget := new ID2D1RenderTarget(pRenderTarget)

        ; 定义画笔
        _struct(tD2D1_COLOR_F,"float;float;float;float",1,1,0,1)
        _struct(tD2D1_BRUSH_PROPERTIES,"float;float;float;float;float;float;float",1)

        oRenderTarget.CreateSolidColorBrush[pRenderTarget,&tD2D1_COLOR_F,&tD2D1_BRUSH_PROPERTIES,pBrush]
        ;oRenderTarget.CreateSolidColorBrush[&tD2D1_COLOR_F,&tD2D1_BRUSH_PROPERTIES,pBrush]
        ; 开始绘图

        oRenderTarget.BeginDraw()
        
        ; 定义背景色
        _struct(tD2D1_COLOR_F1,"float;float;float;float",0,0,1,0)
        oRenderTarget.Clear(&tD2D1_COLOR_F1)

        ; 画直线
        oRenderTarget.DrawLine(0,0,sizeX,sizeY,pBrush,1,0)

        ; 定义椭圆
        radius := (sizeX>sizeY?sizeY:sizeX)/2
        _struct(tD2D1_ELLIPSE,"float;float;float;float",sizeX/2,sizeY/2,radius,radius)
        
        ; 画椭圆
        ;oRenderTarget.FillEllipse(&tD2D1_ELLIPSE, pBrush)
        ;Or maybe to draw ellipse
        oRenderTarget.DrawEllipse(&tD2D1_ELLIPSE, pBrush, 10, 0)

        ; 结束绘图
        oRenderTarget.EndDraw(0,0)
        
        ; 释放资源
        objrelease(pBrush)
}

; 用于定义结构体的函数
_struct(ByRef var,type:="",param*)
{
        if type(type) ="Integer" 
        {
                VarSetCapacity(var,type,0)
                Loop  type//4
                        if param[A_Index]
                                NumPut(param[A_Index],var,(A_Index-1)*A_PtrSize,key%A_Index%)
        }
        else
        {
		key:=StrSplit(type,"`;",A_Space)
                VarSetCapacity(var,key.Length()*A_PtrSize,0)
      for i,n in key
                        if param[A_Index]
                                NumPut(param[A_Index],var,(A_Index-1)*A_PtrSize,n)
        }
}

; 用于创建 Direct2D 对象的函数
_D2D1CreateFactoryObject()
{
        static iid := "{06152247-6f50-465a-9245-118bfd3b6007}"
        _CLSIDFromString(iid,CLSID)
        DllCall("d2d1\D2D1CreateFactory","uint",0,"ptr",&CLSID,"uint*",0,"ptr*",pIFactory)
        return pIFactory
}

; 用于取得 CLSID 结构体的函数
_CLSIDFromString(String,ByRef CLSID)
{
        VarSetCapacity(CLSID,16,0)
        DllCall("ole32\CLSIDFromString","str",String,"ptr",&CLSID)
}

;;
;; 部分Direct2D 接口库
;;
class IUnknown
{
        __New(ptr := 0)
        {

    this.ptr := ptr
                this.vt := NumGet(ptr + 0)
        }
        __Delete()
        {
                return ObjRelease(this.ptr)
        }
        Query(aParams*)
        {  ; Allows (SID, IID) and (IID).
        return ComObjQuery(this.ptr, aParams*)
    }
}

class ID2D1Factory extends IUnknown
{

	CreateHwndRenderTarget(renderTargetProperties,hwndRenderTargetProperties,Byref hwndRenderTarget)
	{
		return DllCall(NumGet(this.vt+14*A_PtrSize),"ptr",this.ptr,"ptr",renderTargetProperties,"ptr",hwndRenderTargetProperties,"ptr*",hwndRenderTarget)
	}

        CreateStrokeStyle(strokeStyleProperties,dashes,dashesCount,Byref strokeStyle)
        {
                return DllCall(NumGet(this.vt+11*A_PtrSize),"ptr",this.ptr,"ptr",strokeStyleProperties,"ptr",dashes,"uint",dashesCount,"ptr*",strokeStyle)
        }
}

class ID2D1Resource extends IUnknown
{
        GetFactory(Byref factory)
        {
                return DllCall(NumGet(this.vt+3*A_PtrSize),"ptr",this.ptr,"ptr","ptr*",factory)
        }
}

class ID2D1RenderTarget extends ID2D1Resource
{
__new(ptr){
	this.ptr:=ptr
	this.vt:=vt:=NumGet(ptr+0)
	this.CreateSolidColorBrush:=DynaCall(NumGet(vt+8*A_PtrSize),"tttt*",this.ptr)
}

        CreateSolidColorBrush2(color,brushProperties,Byref solidColorBrush)
        {
                return DllCall(NumGet(this.vt+8*A_PtrSize),"ptr",this.ptr,"ptr",color,"ptr",brushProperties,"ptr*",solidColorBrush)
        }
        
        BeginDraw()
        {
                return DllCall(NumGet(this.vt+48*A_PtrSize),"ptr",this.ptr)
        }
        
        Clear(D2D1_COLOR_F)
        {
                return DllCall(NumGet(this.vt+47*A_PtrSize),"ptr",this.ptr,"ptr",D2D1_COLOR_F)
        }

        DrawLine(point0,point1,point2,point3,brush,strokeWidth,strokeStyle)
        {
                return DllCall(NumGet(this.vt+15*A_PtrSize),"ptr",this.ptr,"float",point0,"float",point1,"float",point2,"float",point3,"ptr",brush,"float",strokeWidth,"ptr",strokeStyle)
        }
        
        DrawEllipse(ellipse,brush,strokeWidth,strokeStyle)
        {
                return DllCall(NumGet(this.vt+20*A_PtrSize),"ptr",this.ptr,"ptr",ellipse,"ptr",brush,"float",strokeWidth,"ptr",strokeStyle)
        }

        FillEllipse(ellipse,brush)
        {
                return DllCall(NumGet(this.vt+21*A_PtrSize),"ptr",this.ptr,"ptr",ellipse,"ptr",brush)
        }
        
        EndDraw(tag1,tag2)
        {
                return DllCall(NumGet(this.vt+49*A_PtrSize),"ptr",this.ptr,"uint64*",tag1,"uint64*",tag2)
        }
}
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: DynaCall Parameter position adjustment

07 Sep 2017, 15:40

When I run your code I get an error for CreateHwndRenderTarget: https://social.msdn.microsoft.com/Forum ... evelopment

As far as I understand what you want is ["tttt*",2,3,4], otherwise you get ["tttt*",2,1,3,4].
arcticir
Posts: 694
Joined: 17 Nov 2013, 11:32

Re: DynaCall Parameter position adjustment

08 Sep 2017, 09:05

This is a bit strange because I can run the test code normally. (win10-64 h2-32)
thanks.

Return to “Ask for Help”

Who is online

Users browsing this forum: No registered users and 14 guests