Making one's own control

Started by Petrus Vorster, November 24, 2013, 01:32:09 PM

Previous topic - Next topic

Petrus Vorster

Hi all

I want to do something I have never done before. Try to make my own user control.
Not for using it but learning how do these classes and systems all work together.
How to interact with it and how to intercept messages in the Ff system for my control.

If anyone has a few very basic examples on this I can work through (and I mean VERY BASIC) I will be very happy.
Currently I know ZERO about this topic. Any ideas where I can start right at the bottom?
-Regards
Peter

José Roca

VERY BASIC:


#INCLUDE THIS ONCE
#INCLUDE ONCE "windows.inc"

' ========================================================================================
' MYCTRLDATA structure
' ========================================================================================
TYPE MYCTRLDATA
   ' Put here the members that you need
   Dummy AS LONG
END TYPE
' ========================================================================================

' ========================================================================================
' Registers the window class
' ========================================================================================
FUNCTION InitMyCtrl () AS WORD

   LOCAL  wcex AS WNDCLASSEX               ' // WNDCLASSEX structure
   STATIC wAtom AS WORD                    ' // Atom

   ' // Already initialized
   IF wAtom <> 0 THEN
      FUNCTION = wAtom
      EXIT FUNCTION
   END IF

#IF %DEF(%UNICODE)
   LOCAL szClassName AS WSTRINGZ * 256    ' // Class name
#ELSE
   LOCAL szClassName AS ASCIIZ * 256      ' // Class name
#ENDIF

   szClassName        = "MYCONTROL"
   wcex.cbSize        = SIZEOF(wcex)
   wcex.style         = %CS_HREDRAW OR %CS_VREDRAW   ' OR %CS_GLOBALCLASS
   wcex.lpfnWndProc   = CODEPTR(MyCtrlProc)
   wcex.cbClsExtra    = 0
   wcex.cbWndExtra    = 4 ' For pointer to GDIPANIMCTXDATA structure
   wcex.hInstance     = GetModuleHandle(BYVAL %NULL)
   wcex.hIcon         = %NULL
   wcex.hCursor       = LoadCursor(%NULL, BYVAL %IDC_ARROW)
   wcex.hbrBackground = GetStockObject(%WHITE_BRUSH)
   wcex.lpszMenuName  = %NULL
   wcex.lpszClassName = VARPTR(szClassName)
   wcex.hIconSm       = %NULL

   wAtom = RegisterClassEx(wcex)
   FUNCTION = wAtom

END FUNCTION
' ========================================================================================

' ========================================================================================
' Control callback procedure
' ========================================================================================
FUNCTION MyCtrlProc (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, _
                     BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   LOCAL pData AS MYCTRLDATA PTR     ' // Pointer to the control data

   ' // Gets a pointer to button data
   IF ISTRUE hwnd AND wMsg <> %WM_CREATE THEN pdata = GetWindowLong(hwnd, 0)

   SELECT CASE wMsg

      CASE %WM_CREATE
         ' // Allocates memory for the control's data
         pdata = HeapAlloc(GetProcessHeap(), %HEAP_ZERO_MEMORY, SIZEOF(MYCTRLDATA))
         IF pdata THEN
            ' // Stores the pointer in the cbWndExtra member of the window class
            SetWindowLong hwnd, 0, pdata
            EXIT FUNCTION
         ELSE
            ' // Aborts the action
            FUNCTION = -1
            EXIT FUNCTION
         END IF

      CASE %WM_COMMAND, %WM_NOTIFY
         ' // Forwards the message to the parent window
         SendMessage GetParent(hwnd), wMsg, wParam, lParam

'      CASE %WM_ERASEBKGND
'         ' // Don't erase the background to avoid flicker
'         FUNCTION = 1
'         EXIT FUNCTION

      CASE %WM_ENABLE
         ' // Redraws the control
         InvalidateRect hwnd, BYVAL %NULL, 0
         UpdateWindow hwnd
         EXIT FUNCTION

      CASE %WM_DESTROY
         ' // Kills the timer
         ' // Deallocates the memory used for the custom data
         HeapFree(GetProcessHeap(), 0, BYVAL pdata)
         EXIT FUNCTION

   END SELECT

   ' // Default processing for other messages.
   FUNCTION = DefWindowProc(hwnd, wMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


Later, when you would like to see a control that actually does something, look at the ones provided in my include files, such GraphCtx.inc, XPButton.inc, GdipAnimCtx.inc, GdipImageCtx.inc.

Rolf Brandt

Hi Petrus,

here is a very simple Clock control.

Rolf
Rolf Brandt
http://www.rbsoft.eu
http://www.taxifreeware.com
I cook with wine, sometimes I even add it to the food.
(W. C. Fields)

José Roca

Sorry, Rolf, but yours is not a control, but a popup dialog.

Paul Squires

Take a look at the *.inc files for the FireFly controls found in the CustomControls subfolder. That should help get you started. Look at a basic control like FireLink or FireLines.
Paul Squires
PlanetSquires Software

Robert Rioja

What we actually need is a real manual that describes step-by-step how to make FF controls.  I think that many of us would have already produced many controls if we had some real guidance, such as a formal tutorial that we can print and study.  This would have meant more controls, and therefore FF would be more developed.

Robert

José Roca

There is no such thing as FF controls: they are Windows controls. The template that I have provided is all you need: you register a class name for the control and provide a callback to process the messages. Is that easy! The hard part is the code that you have to add in the messages to do what you want.

Petrus Vorster

Hi all

Thanks a million!!!
I will definately give this a shot!

One thing about this forum is that the real smart guys are always willing to help the
"less" smart ones!!! (and in a way we understand!!)
Rare indeed and much appreciated!
-Regards
Peter