Createpen

Started by Petrus Vorster, April 07, 2016, 12:21:19 PM

Previous topic - Next topic

Petrus Vorster

I have this little code in drawing some filled squares:
  hPen = CreatePen(%PS_SOLID, 1, &HFFFFFF)
  hPen = SelectObject(memDC, hPen)

' RoundRect memDC, LT, LT, rc.nright - RB, rc.nbottom - RB, '@rr.corner, @rr.corner

RoundRect memDC, LT, LT, rc.nright , rc.nbottom , @rr.corner, @rr.corner


But i would rather have it draw the colour of the background.
The square will be invisible to the user, but it hosts an image which i want the user to see.
(this is part of a button control)

The first line of this code must be changed to the background colour. I know Paul uses something like that in a Label by determining the first pixel colour.
its a bit new to me. How does one determine that pixel colour? (Since i do have the coordinates already it shouldnt be that hard, I think?)

-Regards
Peter

David Kenny

    Local PCol          As Long    'Pixel Color
    Local hDC           As Dword
    Local p             As PointApi                                 
    hDC = GetDC(hWndForm)
    GetCursorPos p                 'Could use hard-coded values of course
    PCol = GetPixel(hDC, p.x, p.y)


But reading what you are trying to do, you really need to set the background of your image to transparent.  Then the color below will show though.

Petrus Vorster

#2
Back from a little roadtrip...
I think i am going to make a mess here.

I have slightly modified that line from the RRbutton in its .inc file.
The button is indeed transparent, but it need the lines it draws around the button to be either the same colour as the object below it or have them no colour at all, if that can be done..?

I am emulating the new windows buttons in win10 which has no lines and merely changes the icon inside to another colour.
Much of this is done by the RR button, but i had to remove a line to make this work 90%

Works like a dream on a white background, but obviously anything else shows the white lines.
The button wont function unless it draws the rect, but can one make lines invisible?

Changing from %ps_solid to %ps_null only removes one side from the button.
I wonder if Borje Hagsten who made the control will be happy with me trying to mod it?
-Regards
Peter

Petrus Vorster

I am having a good laugh at myself here... I am so going to mess this up  :)

-Regards
Peter

José Roca

Quote
The square will be invisible to the user, but it hosts an image which i want the user to see.
(this is part of a button control)

Make the button ownerdraw and just draw the image...


' ########################################################################################
' Microsoft Windows
' File: CW_ButtonOwnerdraw.pbtpl
' Contents: Template - CWindow with a ownerdraw button
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers III
' Copyright (c) 2016 Jose Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#COMPILE EXE
#DIM ALL
%UNICODE = 1

' // Include files for external files
#INCLUDE ONCE "CWindow.inc"      ' // CWindow class

%IDC_BUTTON = 100

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Set process DPI aware
   AfxSetProcessDPIAware

   ' // Create an instance of the class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   ' // Note: CW_USEDEFAULT is used as the default value When passing 0's as the width and height
   pWindow.CreateWindow(%NULL, "CWindow with ownerdraw button", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   ' // Set the client size
   pWindow.SetClientSize 500, 320
   ' // Center the window
   pWindow.CenterWindow

   ' // Add a button
   LOCAL hButton AS DWORD
   hButton = pWindow.AddButton(pWindow.hwnd, %IDC_BUTTON, "&Ownerdraw button", 300, 150, 50, 50, %WS_VISIBLE OR %WS_TABSTOP OR %BS_OWNERDRAW)
   SetFocus hButton

   ' // Default message pump (you can replace it with your own)
   FUNCTION = pWindow.DoEvents(nCmdShow)

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

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   STATIC pWindow AS IWindow        ' // Reference to the IWindow interface
   STATIC hBitmap AS DWORD

   ' // Process window mesages
   SELECT CASE uMsg

      CASE %WM_CREATE
         ' // Get a reference to the IWindow interface from the CREATESTRUCT structure
         pWindow = CWindow_GetObjectFromCreateStruct(lParam)
         hBitmap = LoadImage(%NULL, EXE.PATH$ & "smallface.bmp", _  ' --> change me!
          %IMAGE_BITMAP, AfxScaleX(50), AfxScaleY(50), %LR_LOADFROMFILE)
         EXIT FUNCTION

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               ' // If the Escape key has been pressed...
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  ' // ... close the application by sending a WM_CLOSE message
                  SendMessage hwnd, %WM_CLOSE, 0, 0
                  EXIT FUNCTION
               END IF
         CASE %IDC_BUTTON
            MSGBOX "Button clicked"
            EXIT FUNCTION

         END SELECT

      CASE %WM_DRAWITEM
         LOCAL pDis AS DRAWITEMSTRUCT PTR
         pDis = lParam
         IF @pDis.CtlId <> %IDC_BUTTON THEN EXIT FUNCTION
         IF hBitmap THEN  DrawState @pDis.hDC, 0, 0, hBitmap, 0, 0, 0, 0, 0, %DST_BITMAP
         FUNCTION = %TRUE
         EXIT FUNCTION

      CASE %WM_DESTROY
         IF hBitmap THEN DeleteObject hBitmap
         ' // End the application
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   ' // Pass unprocessed messages to Windows
   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

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


José Roca

Quote from: Petrus Vorster on April 11, 2016, 01:45:03 PM
I am having a good laugh at myself here... I am so going to mess this up  :)

Don't make things harder that they need to be...

Petrus Vorster

Hi Jose

Thanks Jose.
Now, if i need to change the Icon on the in/out movement of the mouse, how do one go about doing that?

If one look at how many programs looks like nowadays, using vector icons, one will see perhaps a black line icon, but it changes when the mouse enters the button face, much like the RR-button does, except they no longer draw the lines around the buttons.

Programmers knows that all this "bells and whistles" has nothing to do with program performance, but users buy with their eyes and minds. If the looks isn't up to date then people already assume lower performance. I dont sell programs, but i also like the users to have something that looks great too. :)
-Regards
Peter

José Roca

> Now, if i need to change the Icon on the in/out movement of the mouse, how do one go about doing that?

That's more complicated. You may need to subclass the button, check for the WM_MOUSEMOVE and WM_MOUSELEAVE messages, track the mouse movement, etc.

Look at the code of RR_BUTTON or my XPBUTTON control.

José Roca

This example subclasses the ownerdraw button, changes the image when the mouse enters in it and restores the first image when the mouse leaves it.


' ########################################################################################
' Microsoft Windows
' File: CW_ButtonOwnerdraw.pbtpl
' Contents: Template - CWindow with a ownerdraw button
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers III
' Copyright (c) 2014 Jose Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#COMPILE EXE
#DIM ALL
%UNICODE = 1

' // Include files for external files
#INCLUDE ONCE "CWindow.inc"      ' // CWindow class

%IDC_BUTTON = 100

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   ' // Set process DPI aware
   AfxSetProcessDPIAware

   ' // Create an instance of the class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   ' // Create the main window
   ' // Note: CW_USEDEFAULT is used as the default value When passing 0's as the width and height
   pWindow.CreateWindow(%NULL, "CWindow with subclassed ownerdraw button", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
   ' // Set the client size
   pWindow.SetClientSize 500, 320
   ' // Center the window
   pWindow.CenterWindow

   ' // Add a button
   LOCAL hButton AS DWORD
   hButton = pWindow.AddButton(pWindow.hwnd, %IDC_BUTTON, "&Ownerdraw button", 300, 150, 50, 50, _
      %WS_VISIBLE OR %WS_TABSTOP OR %BS_OWNERDRAW, 0, CODEPTR(TextBtn_SubclassProc))
   SetFocus hButton

   ' // Default message pump (you can replace it with your own)
   FUNCTION = pWindow.DoEvents(nCmdShow)

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

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

   STATIC pWindow AS IWindow        ' // Reference to the IWindow interface
   STATIC hBitmap1, hBitmap2 AS DWORD

   ' // Process window mesages
   SELECT CASE uMsg

      CASE %WM_CREATE
         ' // Get a reference to the IWindow interface from the CREATESTRUCT structure
         pWindow = CWindow_GetObjectFromCreateStruct(lParam)
         hBitmap1 = LoadImage(%NULL, EXE.PATH$ & "smallface.bmp", _  ' --> change me!
          %IMAGE_BITMAP, AfxScaleX(50), AfxScaleY(50), %LR_LOADFROMFILE)
         hBitmap2 = LoadImage(%NULL, EXE.PATH$ & "cowgirl.bmp", _  ' --> change me!
          %IMAGE_BITMAP, AfxScaleX(50), AfxScaleY(50), %LR_LOADFROMFILE)
         EXIT FUNCTION

      CASE %WM_COMMAND
         SELECT CASE LO(WORD, wParam)
            CASE %IDCANCEL
               ' // If the Escape key has been pressed...
               IF HI(WORD, wParam) = %BN_CLICKED THEN
                  ' // ... close the application by sending a WM_CLOSE message
                  SendMessage hwnd, %WM_CLOSE, 0, 0
                  EXIT FUNCTION
               END IF
         END SELECT

      CASE %WM_DRAWITEM
         LOCAL pDis AS DRAWITEMSTRUCT PTR
         pDis = lParam
         IF @pDis.CtlId <> %IDC_BUTTON THEN EXIT FUNCTION
         IF GetPropW(GetDlgItem(hwnd, %IDC_BUTTON), "HOT") = 0 THEN
            IF hBitmap1 THEN DrawState @pDis.hDC, 0, 0, hBitmap1, 0, 0, 0, 0, 0, %DST_BITMAP
         ELSE
            IF hBitmap2 THEN DrawState @pDis.hDC, 0, 0, hBitmap2, 0, 0, 0, 0, 0, %DST_BITMAP
         END IF
         FUNCTION = %TRUE
         EXIT FUNCTION

      CASE %WM_DESTROY
         IF hBitmap1 THEN DeleteObject hBitmap1
         IF hBitmap2 THEN DeleteObject hBitmap2
         ' // End the application
         PostQuitMessage 0
         EXIT FUNCTION

   END SELECT

   ' // Pass unprocessed messages to Windows
   FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

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

' ========================================================================================
' Processes messages for the subclassed Button window.
' ========================================================================================
FUNCTION TextBtn_SubclassProc ( _
   BYVAL hwnd   AS DWORD, _                 ' // Control window handle
   BYVAL uMsg   AS DWORD, _                 ' // Type of message
   BYVAL wParam AS DWORD, _                 ' // First message parameter
   BYVAL lParam AS LONG _                   ' // Second message parameter
   ) AS LONG

   SELECT CASE uMsg

      CASE %WM_GETDLGCODE
         ' // All keyboard input
         FUNCTION = %DLGC_WANTALLKEYS
         EXIT FUNCTION

      CASE %WM_LBUTTONDOWN
         MessageBoxW(GetParent(hwnd), "Click", "", %MB_OK)
         EXIT FUNCTION

      CASE %WM_KEYDOWN
         SELECT CASE LO(WORD, wParam)
            CASE %VK_ESCAPE
               SendMessageW(GetParent(hwnd), %WM_CLOSE, 0, 0)
               EXIT FUNCTION
         END SELECT

      CASE %WM_MOUSEMOVE
         ' // Tracks the mouse movement and stores the hot state
         LOCAL trackMouse AS TRACKMOUSEEVENTAPI
         IF GetPropW(hwnd, "HOT") = 0 THEN
            trackMouse.cbSize = SIZEOF(trackMouse)
            trackMouse.dwFlags = %TME_LEAVE
            trackMouse.hwndTrack = hwnd
            trackMouse.dwHoverTime = 1
            TrackMouseEvent(trackMouse)
            SetPropW hwnd, "HOT", %TRUE
            InvalidateRect hwnd, BYVAL %NULL, 0
            UpdateWindow hwnd
         END IF
         EXIT FUNCTION

      CASE %WM_MOUSELEAVE
         ' // Removes the hot state and redraws the button
         RemovePropW hwnd, "HOT"
         InvalidateRect hwnd, BYVAL %NULL, 0
         UpdateWindow hwnd
         EXIT FUNCTION

      CASE %WM_DESTROY
         ' // REQUIRED: Remove control subclassing
         SetWindowLong hwnd, %GWL_WNDPROC, RemoveProp(hwnd, "OLDWNDPROC")
   END SELECT

   FUNCTION = CallWindowProc(GetProp(hwnd, "OLDWNDPROC"), hwnd, uMsg, wParam, lParam)

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


Petrus Vorster

#9
Thanks a million Josè!
I just solved the mod on the rr button too, and it works just fine.

Thanks for the patience and advice everyone.
-Regards
Peter