Author Topic: Winmain / WndProc / DLL question  (Read 8030 times)

0 Members and 1 Guest are viewing this topic.

Offline Frank Brübach

  • Full Member
  • ***
  • Posts: 109
  • User-Rate: +13/-5
Winmain / WndProc / DLL question
« on: November 26, 2009, 11:39:11 PM »
hi jose, all.

1) I have a question (perhaps it's a dummy question) about the including of these two functions "WINMAIN" and "WndProc" to start application. (manual help says: winmain: "is a user-defined function called by Windows to begin execution of an application.") it's necessary to do this one in "main.bas" example or I can include WINMAIN and WNDPROC for my DLL example too? I haven't managed it and tried it some hours without success.

2) I am using sdk window for my examples. Have started to build one sdk window with buttons and two different ways of popup dialogs (not perfect yet) but I am wondering if it's not possible to make the main application shorter and push all stuff into "mydll.bas" file ?

if you push "xmen" button you will get new popup window and new functions (e.g. "clone" window). other things will come as soon I have more time for this project.

my "batmandll_main.bas"

Code: [Select]
#COMPILE EXE
#DIM ALL
#INCLUDE "win32api.inc"

DECLARE FUNCTION ShowPopupDialog LIB "BatmanDLL.DLL" ALIAS "ShowPopupDialog" (BYVAL hParent AS DWORD) AS LONG
DECLARE FUNCTION XMEN LIB "BatmanDLL.DLL" ALIAS "XMEN" (BYVAL hParent AS DWORD) AS LONG
DECLARE FUNCTION popupnew LIB "BatmanDLL.DLL" ALIAS "popupnew" (BYVAL hParent AS DWORD) AS LONG

%IDXMEN = 1005

'------------------------------------------------------------------------------------------------------------------------------------------
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
'------------------------------------------------------------------------------------------------------------------------------------------

   LOCAL hWndMain    AS DWORD
   LOCAL hCtl        AS DWORD
   LOCAL hFont       AS DWORD
   LOCAL wcex        AS WNDCLASSEX
   LOCAL szClassName AS ASCIIZ * 80
   LOCAL rc          AS RECT
   LOCAL szCaption   AS ASCIIZ * 255
   LOCAL nLeft       AS LONG
   LOCAL nTop        AS LONG
   LOCAL nWidth      AS LONG
   LOCAL nHeight     AS LONG

   hFont = GetStockObject(%ANSI_VAR_FONT)

   szClassName        = "MyClassName"
   wcex.cbSize        = SIZEOF(wcex)
   wcex.style         = %CS_HREDRAW OR %CS_VREDRAW
   wcex.lpfnWndProc   = CODEPTR(WndProc)
   wcex.cbClsExtra    = 0
   wcex.cbWndExtra    = 0
   wcex.hInstance     = hInstance
   wcex.hCursor       = LoadCursor (%NULL, BYVAL %IDC_ARROW)
   wcex.hbrBackground = %COLOR_3DFACE + 1
   wcex.lpszMenuName  = %NULL
   wcex.lpszClassName = VARPTR(szClassName)
   wcex.hIcon         = LoadIcon (%NULL, BYVAL %IDI_APPLICATION)
   wcex.hIconSm       = LoadIcon (%NULL, BYVAL %IDI_APPLICATION)
   RegisterClassEx wcex

   szCaption = "Batmans new SDK Window"

   SystemParametersInfo %SPI_GETWORKAREA, 0, BYVAL VARPTR(rc), 0

   nWidth  = (((rc.nRight - rc.nLeft)) + 2) * 0.75
   nHeight = (((rc.nBottom - rc.nTop)) + 2) * 0.70
   nLeft   = ((rc.nRight - rc.nLeft) \ 2) - nWidth \ 2
   nTop    = ((rc.nBottom - rc.nTop) \ 2) - (nHeight \ 2)

   hWndMain = CreateWindowEx(%WS_EX_CONTROLPARENT, _
                             szClassName, _
                             szCaption, _
                             %WS_OVERLAPPEDWINDOW OR _
                             %WS_CLIPCHILDREN, _
                             nLeft, _
                             nTop, _
                             nWidth, _
                             nHeight, _
                             %NULL, _
                             0, _
                             hInstance, _
                             BYVAL %NULL)

   hCtl = CreateWindowEx(0, "BUTTON", "&OpenMe", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
          0, 0, 0, 0, hWndMain, %IDOK, hInstance, BYVAL %NULL)
   IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

   hCtl = CreateWindowEx(0, "BUTTON", "&Close", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
          0, 0, 0, 0, hWndMain, %IDCANCEL, hInstance, BYVAL %NULL)
   IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

   hCtl = CreateWindowEx(0, "BUTTON", "&XMEN", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
          10, 470, 80, 24, hWndMain, %IDXMEN, hInstance, BYVAL %NULL)
   IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

   ShowWindow hWndMain, nCmdShow
   UpdateWindow hWndMain

   LOCAL uMsg AS tagMsg
   WHILE GetMessage(uMsg, %NULL, 0, 0)
      IF ISFALSE IsDialogMessage(hWndMain, uMsg) THEN
         TranslateMessage uMsg
         DispatchMessage uMsg
      END IF
   WEND

   FUNCTION = uMsg.wParam

END FUNCTION

' ========================================================================================
' Main Window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
    LOCAL hDC    AS DWORD
    LOCAL pPaint AS PAINTSTRUCT
    LOCAL tRect  AS RECT
    LOCAL rc AS RECT

   SELECT CASE wMsg

      CASE %WM_CREATE

      CASE %WM_SIZE

         IF wParam <> %SIZE_MINIMIZED THEN
            GetClientRect hWnd, rc
            MoveWindow GetDlgItem(hWnd, %IDOK), (rc.nRight - rc.nLeft) - 185, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
            MoveWindow GetDlgItem(hWnd, %IDCANCEL), (rc.nRight - rc.nLeft) - 95, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
         END IF

      CASE %WM_COMMAND

         SELECT CASE LO(WORD, wParam)

            CASE %IDOK
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  ShowPopupDialog(hwnd)
                  MSGBOX "hello catwoman, come with me :)", %MB_OK, "my popup Test for new DLL" + DATE$
               END IF

            CASE %IDXMEN
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  XMEN(hwnd)
                  MSGBOX "hello Magneto, don't come with me :)", %MB_OK, "my popup Test for new DLL" + DATE$
               END IF

            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hWnd, %WM_CLOSE, 0, 0
                  EXIT FUNCTION
               END IF

         END SELECT

    CASE %WM_CREATE

    CASE %WM_PAINT
        hDC = BeginPaint(hWnd, pPaint)
        GetClientRect hWnd, tRect
        SetBkMode hDC, %TRANSPARENT
        SetTextColor hDC, %YELLOW
        DrawText hDC, "Hello Batman, where are you?", -1, tRect, %DT_SINGLELINE OR %DT_CENTER OR %DT_VCENTER
        EndPaint hWnd, pPaint
        FUNCTION = 1
        EXIT FUNCTION

    CASE %WM_ERASEBKGND
        hDC = wParam
        DrawGradient hDC
        FUNCTION = 1
        EXIT FUNCTION

      CASE %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT, %WM_CTLCOLORLISTBOX, %WM_CTLCOLORSTATIC

      CASE %WM_SYSCOMMAND
         IF (wParam AND &HFFF0) = %SC_CLOSE THEN
            SendMessage hWnd, %WM_CLOSE, 0, 0
            EXIT FUNCTION
         END IF

      CASE %WM_CLOSE

      CASE %WM_DESTROY
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)

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

'==============================================================================
SUB DrawGradient (BYVAL hDC AS DWORD)
'------------------------------------------------------------------------------
    ' Custom draw procedure for gradiend fill
    '--------------------------------------------------------------------------

    LOCAL rectFill AS RECT
    LOCAL rectClient AS RECT
    LOCAL fStep AS SINGLE
    LOCAL hBrush AS DWORD
    LOCAL lOnBand AS LONG

    GetClientRect WindowFromDC(hDC), rectClient
    fStep = rectClient.nbottom / 200

    FOR lOnBand = 0 TO 199
        SetRect rectFill, 0, lOnBand * fStep, rectClient.nright + 1, (lOnBand + 1) * fStep
        hBrush = CreateSolidBrush(RGB(0, 0, 255 - lOnBand))
        Fillrect hDC, rectFill, hBrush
        DeleteObject hBrush
    NEXT

END SUB

more to come, I am sure. / saved exe, dll and "batmandll_main.bas" in zip file.

best regards, frank

 
« Last Edit: November 26, 2009, 11:40:57 PM by Frank Brübach »

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2485
  • User-Rate: +204/-0
Re: Winmain / WndProc / DLL question
« Reply #1 on: November 27, 2009, 12:22:39 AM »
Quote
it's necessary to do this one in "main.bas" example or I can include WINMAIN and WNDPROC for my DLL example too?

You can't put them in a DLL, they must be in the main application.

Offline Frederick J. Harris

  • Hero Member
  • *****
  • Posts: 914
  • User-Rate: +16/-0
    • Frederick J. Harris
Re: Winmain / WndProc / DLL question
« Reply #2 on: November 27, 2009, 04:16:25 AM »
Hi Frank!

     I prefer to keep my WinMain() function as short as possible.  The only window I RegesterClassEx() there or CreateWindow() there is the main program window.  All other windows ( controls, i.e., buttons, edit controls, etc.) I create during the WM_CREATE message.  You can get the hInstance you need to create other windows using CreateWindow without resorting to globals in a multitude of ways.

Fred

Offline Frank Brübach

  • Full Member
  • ***
  • Posts: 109
  • User-Rate: +13/-5
Re: Winmain / WndProc / DLL question
« Reply #3 on: November 27, 2009, 02:34:10 PM »
hi fred! thanks for the hint.

do you mean such way of window creating ?

Code: [Select]
CASE %WM_CREATE
      hInstance = GetModuleHandle("")
      ' Create font used by container
      hFont = GetStockObject(%DEFAULT_GUI_FONT)

     ' Create the Name edit control
      hWndChild = CreateWindowEx(%WS_EX_CLIENTEDGE, _                                 'Child ' extended styles
                                 "Edit", _                                            ' class name
                                 "", _                                                ' caption
                                 %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR _         ' window styles
                                 %ES_LEFT OR %ES_AUTOHSCROLL, _                       ' class styles
                                 230, 30, _                                           ' left, top
                                 358, 21, _                                           ' width, height
                                 hWnd, %IDC_NAME, _                                   ' handle of parent, control ID
                                 hInstance, BYVAL %NULL)                              ' handle of instance, creation parameters
      SendMessage hWndChild, %WM_SETFONT, hFont, %TRUE 'Child

      ' Set the text limit
      SendMessage hWndChild, %EM_SETLIMITTEXT, 64, 0 '   

that's correct ? or do you have any example for showing ? would help.

thanks. nice day, frank

Offline Frederick J. Harris

  • Hero Member
  • *****
  • Posts: 914
  • User-Rate: +16/-0
    • Frederick J. Harris
Re: Winmain / WndProc / DLL question
« Reply #4 on: November 27, 2009, 11:59:22 PM »
Yea, that's it Frank!  Here's another way to get it.  During the WM_CREATE message the lParam is a pointer to a CREATESTRUCT that contains the various information from the CreateWindow() call down in WinMain().  So you can get it like this too...

Code: [Select]
Type WndEventArgs
  wParam As Long
  lParam As Long
  hWnd   As Dword
  hInst  As Dword
End Type

Function fnWndProc_OnCreate(wea As WndEventArgs) As Long
  Local pCreateStruct As CREATESTRUCT Ptr
  Local hBtn As Dword

  pCreateStruct=wea.lParam
  wea.hInst=@pCreateStruct.hInstance
  hBtn=CreateWindow("button","Click Me!",%WS_CHILD Or %WS_VISIBLE,100,20,120,25,wea.hWnd,%IDC_BUTTON1,wea.hInst,Byval 0)
  hBtn=CreateWindow("button","But Not Me!",%WS_CHILD Or %WS_VISIBLE,100,60,120,25,wea.hWnd,%IDC_BUTTON2,wea.hInst,Byval 0)

  fnWndProc_OnCreate=0
End Function

In addition, there's yet another way to get the hInstance out of the Class Structure with GetWindowLong() I believe.  I'd have to look that one up though.
« Last Edit: November 28, 2009, 12:00:58 AM by Frederick J. Harris »

Offline Frank Brübach

  • Full Member
  • ***
  • Posts: 109
  • User-Rate: +13/-5
Re: Winmain / WndProc / DLL question
« Reply #5 on: November 30, 2009, 09:11:09 PM »
thank you fred for your last infos. I will try to use this new kind of createWindow one day, I didn't know this way at all :)

my little batman.dll project increases.

if you open "xmen" button in my first dialog (left side, bottom) there will open new sdk window with more buttons. Click for example the top button "myHobby!" to see how a new picture will open. "load image" button does work for 50 perCent (this button is already looking for new images) but I will try to build new loading image features to replace and load new picture you like.  - it's a great adventure to build new dll's and popup windows. I like it very mucho and my powerbasic background becomes better and better ;)

"batmanDLL_main2.bas"

Code: [Select]
#COMPILE EXE
#DIM ALL
#INCLUDE "win32api.inc"
#INCLUDE "EditCtrl.inc"

%IDC_TEXT = 200

GLOBAL hViewer AS DWORD
GLOBAL hMemDC AS DWORD
GLOBAL hBitmap AS DWORD


DECLARE FUNCTION ShowPopupDialog LIB "BatmanDLL2.DLL" ALIAS "ShowPopupDialog" (BYVAL hParent AS DWORD) AS LONG
DECLARE FUNCTION XMEN LIB "BatmanDLL2.DLL" ALIAS "XMEN" (BYVAL hParent AS DWORD) AS LONG
DECLARE FUNCTION popupnew LIB "BatmanDLL2.DLL" ALIAS "popupnew" (BYVAL hParent AS DWORD) AS LONG
DECLARE FUNCTION ShowPopupDialox LIB "BatmanDLL2.DLL" ALIAS "ShowPopupDialox" (BYVAL hParent AS DWORD) AS LONG

GLOBAL hListBox   AS DWORD
GLOBAL hStatusbar AS DWORD

%IDXMEN = 1005
%IDC_STATUSBAR = 1006
%IDC_NAME = 1007
%IDOPENX = 1008

'------------------------------------------------------------------------------------------------------------------------------------------
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
'------------------------------------------------------------------------------------------------------------------------------------------

   LOCAL hWndMain    AS DWORD
   LOCAL hCtl        AS DWORD
   LOCAL hFont       AS DWORD
   LOCAL wcex        AS WNDCLASSEX
   LOCAL szClassName AS ASCIIZ * 80
   LOCAL rc          AS RECT
   LOCAL szCaption   AS ASCIIZ * 255
   LOCAL nLeft       AS LONG
   LOCAL nTop        AS LONG
   LOCAL nWidth      AS LONG
   LOCAL nHeight     AS LONG

   hFont = GetStockObject(%ANSI_VAR_FONT)

   szClassName        = "MyClassName"
   wcex.cbSize        = SIZEOF(wcex)
   wcex.style         = %CS_HREDRAW OR %CS_VREDRAW
   wcex.lpfnWndProc   = CODEPTR(WndProc)
   wcex.cbClsExtra    = 0
   wcex.cbWndExtra    = 0
   wcex.hInstance     = hInstance
   wcex.hCursor       = LoadCursor (%NULL, BYVAL %IDC_ARROW)
   wcex.hbrBackground = %COLOR_3DFACE + 1
   wcex.lpszMenuName  = %NULL
   wcex.lpszClassName = VARPTR(szClassName)
   wcex.hIcon         = LoadIcon (%NULL, BYVAL %IDI_APPLICATION)
   wcex.hIconSm       = LoadIcon (%NULL, BYVAL %IDI_APPLICATION)
   RegisterClassEx wcex

   szCaption = "Batmans new SDK Window"

   SystemParametersInfo %SPI_GETWORKAREA, 0, BYVAL VARPTR(rc), 0

   nWidth  = (((rc.nRight - rc.nLeft)) + 2) * 0.75
   nHeight = (((rc.nBottom - rc.nTop)) + 2) * 0.70
   nLeft   = ((rc.nRight - rc.nLeft) \ 2) - nWidth \ 2
   nTop    = ((rc.nBottom - rc.nTop) \ 2) - (nHeight \ 2)

   hWndMain = CreateWindowEx(%WS_EX_CONTROLPARENT, _
                             szClassName, _
                             szCaption, _
                             %WS_OVERLAPPEDWINDOW OR _
                             %WS_CLIPCHILDREN, _
                             nLeft, _
                             nTop, _
                             nWidth, _
                             nHeight, _
                             %NULL, _
                             0, _
                             hInstance, _
                             BYVAL %NULL)

   hCtl = CreateWindowEx(0, "BUTTON", "&OpenMe", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
          0, 0, 0, 0, hWndMain, %IDOK, hInstance, BYVAL %NULL)
   IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

   hCtl = CreateWindowEx(0, "BUTTON", "&Close", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
          0, 0, 0, 0, hWndMain, %IDCANCEL, hInstance, BYVAL %NULL)
   IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

   hCtl = CreateWindowEx(0, "BUTTON", "&XMEN", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
          10, 470, 80, 24, hWndMain, %IDXMEN, hInstance, BYVAL %NULL)
   IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0

   hCtl = CreateWindowEx(0, "BUTTON", "&NEWO", %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
          90, 470, 80, 24, hWndMain, %IDOPENX, hInstance, BYVAL %NULL)
   IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0


   ShowWindow hWndMain, nCmdShow
   UpdateWindow hWndMain

   LOCAL uMsg AS tagMsg
   WHILE GetMessage(uMsg, %NULL, 0, 0)
      IF ISFALSE IsDialogMessage(hWndMain, uMsg) THEN
         TranslateMessage uMsg
         DispatchMessage uMsg
      END IF
   WEND

   FUNCTION = uMsg.wParam

END FUNCTION

' ========================================================================================
' Main Window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
    LOCAL hDC    AS DWORD
    LOCAL pPaint AS PAINTSTRUCT
    LOCAL tRect  AS RECT
    LOCAL rc AS RECT
  LOCAL hWndChild     AS DWORD    ' handle of child window
  LOCAL hFont         AS DWORD    ' handle of font used by form
  LOCAL hImage        AS DWORD    ' handle of bitmap, icon, cursor or metafile
  LOCAL lMsgResult    AS LONG     ' value returned to message after message is processed
  LOCAL hInstance     AS DWORD
  LOCAL szPath        AS ASCIIZ * %MAX_PATH
  LOCAL szItem AS ASCIIZ * 255
  STATIC hFocus       AS DWORD
   LOCAL strText AS STRING
   LOCAL hCtl    AS DWORD


   SELECT CASE wMsg

      CASE %WM_CREATE

      CASE %WM_SIZE

         IF wParam <> %SIZE_MINIMIZED THEN
            GetClientRect hWnd, rc
            MoveWindow GetDlgItem(hWnd, %IDOK), (rc.nRight - rc.nLeft) - 185, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
            MoveWindow GetDlgItem(hWnd, %IDCANCEL), (rc.nRight - rc.nLeft) - 95, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
         END IF

      CASE %WM_COMMAND

         SELECT CASE LO(WORD, wParam)

            CASE %IDOK
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  ShowPopupDialog(hwnd)
                  MSGBOX "hello catwoman, come with me :)", %MB_OK, "my popup Test for new DLL" + DATE$
               END IF

            CASE %IDXMEN
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  XMEN(hwnd)
                  MSGBOX "hello Magneto, don't come with me :)", %MB_OK, "my popup Test for new DLL" + DATE$
               END IF

            CASE %IDCANCEL
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  SendMessage hWnd, %WM_CLOSE, 0, 0
                  EXIT FUNCTION
               END IF

               CASE %IDOPENX
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  ShowPopupDialog(hwnd)
                  MSGBOX "hello catwoman, come with me :)", %MB_OK, "my popup Test for new DLL" + DATE$
               END IF

         END SELECT

    CASE %WM_CREATE
      hInstance = GetModuleHandle("")
      ' Create font used by container
      hFont = GetStockObject(%DEFAULT_GUI_FONT)

     ' Create the Name edit control
      hWndChild = CreateWindowEx(%WS_EX_CLIENTEDGE, _                                 'Child ' extended styles
                                 "Edit", _                                            ' class name
                                 "", _                                                ' caption
                                 %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR _         ' window styles
                                 %ES_LEFT OR %ES_AUTOHSCROLL, _                       ' class styles
                                 230, 30, _                                           ' left, top
                                 358, 21, _                                           ' width, height
                                 hWnd, %IDC_NAME, _                                   ' handle of parent, control ID
                                 hInstance, BYVAL %NULL)                              ' handle of instance, creation parameters
      SendMessage hWndChild, %WM_SETFONT, hFont, %TRUE 'Child

      ' Set the text limit
      SendMessage hWndChild, %EM_SETLIMITTEXT, 64, 0 '

    CASE %WM_PAINT
        hDC = BeginPaint(hWnd, pPaint)
        GetClientRect hWnd, tRect
        SetBkMode hDC, %TRANSPARENT
        SetTextColor hDC, %YELLOW
        DrawText hDC, "Hello Batman, where are you?", -1, tRect, %DT_SINGLELINE OR %DT_CENTER OR %DT_VCENTER
        EndPaint hWnd, pPaint
        FUNCTION = 1
        EXIT FUNCTION

    CASE %WM_ERASEBKGND
        hDC = wParam
        DrawGradient hDC
        FUNCTION = 1
        EXIT FUNCTION

    CASE %WM_CREATE
        hDC = GetDc(hViewer)
         ' // Create the controls
         hFont = GetStockObject(%ANSI_VAR_FONT)
         hViewer = CreateWindowEx(%WS_EX_CLIENTEDGE, "BitMapViewer", "", _
                     %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, _
                     0, 0, 426, 426, hwnd, 10, GetModuleHandle(""), BYVAL %NULL)
         hCtl = CreateWindowEx(0,"Static","BatmanText" , _ '"Static", "Text:"
                    %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT, _
                    438, 241, 150, 16, hwnd,  -1, GetModuleHandle(""), BYVAL %NULL)
         IF hFont THEN SendMessage hCtl, %WM_SETFONT, hFont, 0
         hCtl = CreateWindowEx(%WS_EX_CLIENTEDGE, "Edit", "LionBASIC", _
                    %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_CENTER OR %ES_AUTOHSCROLL, _
                    437, 257, 148, 19, hwnd, %IDC_TEXT, GetModuleHandle(""), BYVAL %NULL)

        GetClientRect hViewer, rc
        ReleaseDc hViewer, hDC
        strText = Edit_GetText(GetDlgItem(hwnd, %IDC_TEXT))
        'ImgDrawText strText
         'EXIT FUNCTION

      CASE %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT, %WM_CTLCOLORLISTBOX, %WM_CTLCOLORSTATIC

      CASE %WM_SYSCOMMAND
         IF (wParam AND &HFFF0) = %SC_CLOSE THEN
            SendMessage hWnd, %WM_CLOSE, 0, 0
            EXIT FUNCTION
         END IF

      CASE %WM_CLOSE

      CASE %WM_DESTROY
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)

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

'==============================================================================
SUB DrawGradient (BYVAL hDC AS DWORD)
'------------------------------------------------------------------------------
    ' Custom draw procedure for gradiend fill
    '--------------------------------------------------------------------------

    LOCAL rectFill AS RECT
    LOCAL rectClient AS RECT
    LOCAL fStep AS SINGLE
    LOCAL hBrush AS DWORD
    LOCAL lOnBand AS LONG

    GetClientRect WindowFromDC(hDC), rectClient
    fStep = rectClient.nbottom / 200

    FOR lOnBand = 0 TO 199
        SetRect rectFill, 0, lOnBand * fStep, rectClient.nright + 1, (lOnBand + 1) * fStep
        hBrush = CreateSolidBrush(RGB(0, 0, 255 - lOnBand))
        Fillrect hDC, rectFill, hBrush
        DeleteObject hBrush
    NEXT

END SUB

test this example, if you like or anybody else. best regards, good evening, frank
« Last Edit: December 01, 2009, 12:37:42 AM by Frank Brübach »

Offline Frank Brübach

  • Full Member
  • ***
  • Posts: 109
  • User-Rate: +13/-5
Re: Winmain / WndProc / DLL question
« Reply #6 on: December 01, 2009, 12:48:22 AM »
..last not least ;)

I have managed to built in GDIp Features for my DLL, I thought it was impossible to do all in my DLL ! So I have included two complete different ways to open Jpg/PNG/Bmp Images with powerbasic.

open "x-men testdialog": if you push the second new button "photoPix!" you load a jpg picture created a
checkered pattern of black pixels in the bitmap. not so bad, isn't it ? ;)

you can also draw rectangles in this dialog and make black holes.

nice evening, good night, frank
dll, exe and pictures I add here.
« Last Edit: December 01, 2009, 12:52:20 AM by Frank Brübach »

Offline Steve Hutchesson

  • Jr. Member
  • **
  • Posts: 83
  • User-Rate: +6/-5
    • The MASM Forum
Re: Winmain / WndProc / DLL question
« Reply #7 on: December 08, 2009, 02:29:16 AM »
Fred,

I learnt a hard lesson recently with the WM_CREATE message. My current editor written in MASM uses a rich edit 2+ control and while it worked perfectly on Win2000 and the XP Sp3 I currently use, a number of different programs appear to use a hook of some type that killed it stone dead in the WM_CREATE message before CreateWindowEx() had returned. It was the call to the rich edit control where it exited with no warning.

Solution was simple, I put the richedit call after the creation of the main window and it works perfectly. Two apps caused the problem, RealVNC and the accessory software that came with my NVIDIA video card.

Offline Frederick J. Harris

  • Hero Member
  • *****
  • Posts: 914
  • User-Rate: +16/-0
    • Frederick J. Harris
Re: Winmain / WndProc / DLL question
« Reply #8 on: December 08, 2009, 04:44:23 AM »
I've never seen that Hutch.  So you had the CreateWindowEx call to create your RichEdit control in the WM_CREATE handler/message, and the whole app failed, or just that one CreateWindowEx call?  I realize your editor (which I've used and like) can't do much after such a call fails.

So what are you recommending?  You aren't using WM_CREATE to create child windows anymore?  I suppose it doesn't have to be done that way; I do believe that is more or less standard practice though.  What do other folks do?

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2485
  • User-Rate: +204/-0
Re: Winmain / WndProc / DLL question
« Reply #9 on: December 08, 2009, 05:59:29 AM »
 
When I code by hand, I like to create the controls in WinMain, right after the creation of the main window.

Offline Steve Hutchesson

  • Jr. Member
  • **
  • Posts: 83
  • User-Rate: +6/-5
    • The MASM Forum
Re: Winmain / WndProc / DLL question
« Reply #10 on: December 08, 2009, 06:06:31 AM »
Fred,

It was one of those that jumped up and bit you with no warning. The code written in the WM_CREATE handler was correct and worked on a normal installation of Windows but when I put the NVIDIA software in an set an option for a particular effect suddenly my editor did not work so I had to turn it off. When I got the same effect with RealVNC I used 2 computers to solved the problem, used the editor from one computer to edit and change the code and kept testing it on the other where it would not start.

I tracked the crash point with a simple messagebox and kept moving it along the load sequence until it did not appear. It happened in the WM_CREATE handler in the WndProc so I moved the call to CreateWindowEx() for the rich edit control back to the WinMain after the main window was created and it has tested fine ever since. I think its a timing issue down in the guts of the API that was triggered by the characteristics of the installed software, RealVNC and the NVIDIA software.

Offline Patrice Terrier

  • ROMs
  • Hero Member
  • *****
  • Posts: 934
  • User-Rate: +62/-1
    • www.zapsolution.com
Re: Winmain / WndProc / DLL question
« Reply #11 on: December 08, 2009, 07:30:10 AM »
Quote
When I code by hand, I like to create the controls in WinMain, right after the creation of the main window.

I am also doing this myself, either diretcly into the Winmain section or in subroutine that is being called, just before showing the main window.

It is my experience that this is the best way to do it, especially when you need to subclass existing controls.

And for some common controls, then you need to act before the processing of the WM_CREATE message to change their dwStyle on the fly! (see also WM_NCCREATE ).

...
« Last Edit: December 08, 2009, 07:34:16 AM by Patrice Terrier »
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com