Announcement

Collapse
No announcement yet.

Non-DDT use of Callbacks ?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Non-DDT use of Callbacks ?

    I was wondering:

    Are Callback functions only usable with DDT code ?

    Are the CBxxx functions used with callbacks a product of the DDT engine or simply something associated with a callback ?

    Callback coding style would be useful for non-DDT apps, so I was wondering how it can be used.
    Chris Boss
    Computer Workshop
    Developer of "EZGUI"
    http://cwsof.com
    http://twitter.com/EZGUIProGuy

  • #2
    message crackers?

    You talking about message crackers Chris? I always do that to avoid long Select Case blocks. The two ways I do it are either like this...

    Code:
    #Compile Exe
    #Include "Win32api.inc"
    
    Type WndEventArgs
      wParam               As Long          'Package parameters to Window Procedure in TYPE
      lParam               As Long
      hWnd                 As Dword
      hInst                As Dword
    End Type
    
    
    Function fnWndProc_OnCreate(Wea As WndEventArgs) As Long
      Local lpCreateStruct As CREATESTRUCT Ptr
    
      lpCreateStruct=Wea.lParam   'Can use GetModuleHandle() here instead, or, use Global (Hate Globals!)
      [email protected]
    
      fnWndProc_OnCreate=0
    End Function
    
    
    Function fnWndProc_OnPaint(Wea As WndEventArgs) As Long
      Local pszString As Asciiz Ptr
      Local lpPaint As PAINTSTRUCT
      Local strText As String
      Local hDC As Long
    
      hDC=BeginPaint(Wea.hWnd,lpPaint)
      Call SetBkMode(hDC,%TRANSPARENT)
      strText = "Hello, World!"
      Call TextOut(hDC,0,0,Byval Strptr(strText),Len(strText))
      Call EndPaint(Wea.hWnd,lpPaint)
    
      fnWndProc_OnPaint=0
    End Function
    
    
    Function fnWndProc_OnDestroy(Wea As WndEventArgs) As Long
      Call PostQuitMessage(0)
      fnWndProc_OnDestroy=0
    End Function
    
    
    Function fnWndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long
      Static Wea As WndEventArgs
    
      Select Case As Long wMsg
        Case %WM_CREATE
          Wea.hWnd=hWnd : Wea.wParam=wParam : Wea.lParam=lParam
          fnWndProc=fnWndProc_OnCreate(Wea)
          Exit Function
        Case %WM_PAINT
          Wea.hWnd=hWnd : Wea.wParam=wParam : Wea.lParam=lParam
          fnWndProc=fnWndProc_OnPaint(Wea)
          Exit Function
        Case %WM_DESTROY
          Call PostQuitMessage(0)
          fnWndProc=fnWndProc_OnDestroy(Wea)
          Exit Function
      End Select
    
      fnWndProc=DefWindowProc(hWnd,wMsg,wParam,lParam)
    End Function
    
    Function WinMain(ByVal hIns As Long,ByVal hPrev As Long,ByVal lpCL As Asciiz Ptr,ByVal iShow As Long) As Long
      Local winclass As WndClassEx
      Local szAppName As Asciiz*16
      Local Msg As tagMsg
      Local hWnd As Dword
    
      szAppName="Form1"
      winclass.cbSize=SizeOf(winclass)
      winclass.style=%CS_HREDRAW Or %CS_VREDRAW
      winclass.lpfnWndProc=CodePtr(fnWndProc)
      winclass.cbClsExtra=0
      winclass.cbWndExtra=0
      winclass.hInstance=hIns
      winclass.hIcon=LoadIcon(%NULL, ByVal %IDI_APPLICATION)
      winclass.hCursor=LoadCursor(%NULL, ByVal %IDC_ARROW)
      winclass.hbrBackground=%COLOR_BTNFACE+1
      winclass.lpszMenuName=%NULL
      winclass.lpszClassName=VarPtr(szAppName)
      Call RegisterClassEx(winclass)
      hWnd=CreateWindow(szAppName,"Form1",1040384,200,100,325,300,0,0,hIns,ByVal 0)
      Call ShowWindow(hWnd,iShow)
      While GetMessage(Msg,%NULL,0,0)
        TranslateMessage Msg
        DispatchMessage Msg
      Wend
    
      Function=msg.wParam
    End Function
    or like this...

    Code:
    #Compile Exe
    #Include "Win32api.inc"
    
    Type WndEventArgs
      wParam As Long
      lParam As Long
      hWnd   As Dword
      hInst  As Dword
    End Type
    
    Declare Function FnPtr(wea As WndEventArgs) As Long
    
    Type MessageHandler
      wMessage As Long
      dwFnPtr As Dword
    End Type
    Global MsgHdlr() As MessageHandler
    
    
    Function fnWndProc_OnCreate(wea As WndEventArgs) As Long
      Local pCreateStruct As CREATESTRUCT Ptr
    
      pCreateStruct=wea.lParam
      wea.[email protected]
      fnWndProc_OnCreate=0
    End Function
    
    
    Function fnWndProc_OnNotify(wea As WndEventArgs) As Long
      fnWndProc_OnNotify=0
    End Function
    
    
    Function fnWndProc_OnClose(wea As WndEventArgs) As Long
      Call PostQuitMessage(0)
      fnWndProc_OnClose=0
    End Function
    
    
    Function fnWndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long
      Static wea As WndEventArgs
      Register iReturn As Long
      Register i As Long
    
      For i=0 To 2
        If wMsg=MsgHdlr(i).wMessage Then
           wea.hWnd=hWnd: wea.wParam=wParam: wea.lParam=lParam
           Call Dword MsgHdlr(i).dwFnPtr Using FnPtr(wea) To iReturn
           fnWndProc=iReturn
           Exit Function
        End If
      Next i
    
      fnWndProc=DefWindowProc(hWnd,wMsg,wParam,lParam)
    End Function
    
    
    Sub AttachMessageHandlers()
      ReDim MsgHdlr(2) As MessageHandler  'Associate Windows Message With Message Handlers
      MsgHdlr(0).wMessage=%WM_CREATE   :   MsgHdlr(0).dwFnPtr=CodePtr(fnWndProc_OnCreate)
      MsgHdlr(1).wMessage=%WM_NOTIFY   :   MsgHdlr(1).dwFnPtr=CodePtr(fnWndProc_OnNotify)
      MsgHdlr(2).wMessage=%WM_CLOSE    :   MsgHdlr(2).dwFnPtr=CodePtr(fnWndProc_OnClose)
    End Sub
    
    
    Function WinMain(ByVal hIns As Long,ByVal hPrev As Long,ByVal lpCL As Asciiz Ptr,ByVal iShow As Long) As Long
      Local hWnd As Dword
      Local winclass As WndClassEx
      Local szAppName As Asciiz * 16
      Local Msg As tagMsg
    
      szAppName="NewGrid"
      Call AttachMessageHandlers()
      winclass.cbSize=SizeOf(winclass)
      winclass.style=%CS_HREDRAW Or %CS_VREDRAW
      winclass.lpfnWndProc=CodePtr(fnWndProc)
      winclass.cbClsExtra=0
      winclass.cbWndExtra=0
      winclass.hInstance=hIns
      winclass.hIcon=LoadIcon(%NULL, ByVal %IDI_APPLICATION)
      winclass.hCursor=LoadCursor(%NULL, ByVal %IDC_ARROW)
      winclass.hbrBackground=GetStockObject(%LTGRAY_BRUSH)
      winclass.lpszMenuName=%NULL
      winclass.lpszClassName=VarPtr(szAppName)
      RegisterClassEx winclass
      hWnd=CreateWindow(szAppName,"Form1",%WS_OVERLAPPEDWINDOW,200,100,325,300,0,0,hIns,ByVal 0)
      Call ShowWindow(hWnd,iShow)
      While GetMessage(Msg,%NULL,0,0)
        TranslateMessage Msg
        DispatchMessage Msg
      Wend
    
      Function=msg.wParam
    End Function
    ???
    Fred
    "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

    Comment


    • #3
      No, I am not refering to message crackers.

      I am refering to the Callback function concept itself.

      PB Callbacks generate values for the CBxxx functions, rather than pass actual parameters (hWnd&, Msg&, wParam&, lParam&).

      Currently callbacks are used with Dialogs (aka. Dialog Procedure) and control callbacks (aka. WM_COMMAND message processing).

      My question is:

      Can the Callback functionality (and syntax) be used with non-DDT code ?

      For example, lets say you write a subclassing routine and instead of passing a normal function as the new window procedure address, could you use a callback function address ?

      For example would:

      NewWindowAddress = VARPTR(MyCallBackFunction)
      SetWindowLong hCtrl&, %GWL_WNDPROC, NewWindowAddress

      work and would the callback function properly process the CBxxx functions (or as best it can).
      Chris Boss
      Computer Workshop
      Developer of "EZGUI"
      http://cwsof.com
      http://twitter.com/EZGUIProGuy

      Comment


      • #4
        "CALLBACK FUNCTION DialogProc() AS LONG " is simply (proprietary) shorthand for:
        Code:
        FUNCTION DialogProc (BYVAL CBHNDL AS LONG, BYVAL CBMSG AS LONG,_
                BYVAL CBWPARAM AS LONG, BYVAL CBLPARAM AS LONG) AS LONG
        Put that into a PB/CC program where all the "CBxxxx" are not reserved words, and bingo you have a window procedure using all the CBxxxxx words.

        Of course to complete the CBxxx functions you'll need a couple of MACROs...
        Code:
        MACRO CBCTL       = LOWRD(CBWPARAM)
        MACRO CBCTLMSG = HIWRD(CBWPARAM)
        But to answer yiour question directly.....

        No, you may not use "CALLBACK FUNCTION" with other window procedures... it may "work" but since it's proprietary AND the doc says the CALLBACK FUNCTION is reserved for procedures used in the CALLBACK option of either CONTROL ADD or DIALOG SHOW, that would be a pure crapshoot.

        ALSO, CBHNDL is always a handle to the owner window, so using "CALLBACK FUNCTION" syntax for a subclass procedure would always result in the wrong "hwnd" value when "CBHNDL" is used therein.


        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment

        Working...
        X