Announcement

Collapse
No announcement yet.

Palette in simple cases

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

  • Palette in simple cases

    I made a simple form, which has enough childs.
    I imagine that there are two ways to avoid troubles in 256-colors mode.

    1) To use GetNearestColor
    2) To set a palette.

    I prefer last, but, as I understand, it's necessary to do this for each hDC
    (possible, but not very interesting - it's not a bitmap).

    Guys, what are you doing in similar situations ? (when it's enough to add 3-4 own colors into system palette ?).



    ------------------
    E-MAIL: [email protected]

  • #2
    Semen, (we already discussed on it...) It requires many steps.

    1- My programs use the old fashion LOGPALETTE declaration. It was:
    Code:
    TYPE LOGPALETTE
      palVersion AS WORD
      palNumEntries AS WORD
      palPalEntry(1) AS PALETTEENTRY 
    END TYPE
    while the newer one is:
    Code:
    TYPE LOGPALETTE
      palVersion AS WORD
      palNumEntries AS WORD
      palPalEntry as PALETTEENTRY PTR  ' (I don't know how this can work!)
    END TYPE
    2- On the main window %WM_CREATE message you create the PALETTE. The following works only if you have the old LOGPALETTE declaration
    Code:
    STATIC lPl AS LOGPALETTE PTR
    lPl = LocalAlloc( %LMEM_FIXED OR %LMEM_ZEROINIT, SIZEOF( @lPl ) + 255 * 4 )
    @lpl.palVersion    = &h300
    @lpl.PalNumEntries = %WxPbccCOLmaxpal + 1
    FOR i = 0 TO ...
      @lpl.PalPalEntry( i ).peRed   = ...
      @lpl.PalPalEntry( i ).peGreen = ...
      @lpl.PalPalEntry( i ).peBlue  = ...
      @lpl.PalPalEntry( i ).peFlags = ...
    NEXT i
    hPalette = CreatePalette( @lpl )
    3- On both the %WM_CREATE, %WM_DISPLAYCHANGE, %WM_QUERYNEWPALETTE and %WM_PALETTECHANGED:
    Code:
    if wMsg <> %WM_PALETTECHANGED or hWnd <> wParam then          ' this is to avoid an endless loop
      hDc = GetWindowDc( hWnd )
      if GetDeviceCaps( hDc, %RASTERCAPS ) and %RC_PALETTE then   ' this is to avoid the calls on a more-than-256 color screen 
        hDc = GetWindowDc( hWnd )
        SelectPalette hDc, hPalette, %false
        UnrealizeObject hPalette
        RealizePalette hDc
      end if
      releasedc hWnd, hDc
    end if
    4- On %WM_DESTROY:
    Code:
    DeleteObject hPalette
    LocalFree lPl
    5- On child windows %WM_PAINT:
    Code:
    hDc = BeginPaint( hWnd, ps )
    if GetDeviceCaps( hDc, %RASTERCAPS ) and %RC_PALETTE then    
      SelectPalette  hDc, hPalette, %true
      RealizePalette hDc
    end if 
    ... your drawing code
    EndPaint hWnd, ps
    Hope I haven't forget anything...


    ------------------




    [This message has been edited by Aldo Cavini (edited April 02, 2001).]
    Rgds, Aldo

    Comment


    • #3
      Aldo --
      Thanks for explanations, but I am aware how to build logical palettes.
      (BTW, usung an array of Longs requires much less code).

      Look your step 5 and imagine standart control (static/textbox/combobox).
      Background/foreground color is not from system palette.
      I am ready to make superclass, but where to realize own palette ?

      Theoretically a solution is to add some "static" colors to system palette without affecting other apps.
      Unf., not sure that it's possible.



      ------------------
      E-MAIL: [email protected]

      Comment


      • #4
        Use OWNERDRAW. I used it on a menu bar, in which I had to select a color to interactive draw on a window. The menu item has the %MF_OWNERDRAW flag set. On the %WM_DRAWITEM event you can select the palette:
        Code:
        LOCAL DrawIt AS DRAWITEMSTRUCT PTR
          DrawIt = lParam
          SelectPalette @DrawIt.hDc, hPalette, %true
          RealizePalette @DrawIt.hDc
          ... draw the menu item
        This works fine on a menu item. I think it will work also on other items.

        ------------------
        Rgds, Aldo

        Comment


        • #5
          Originally posted by Semen Matusovski:
          I am ready to make superclass, but where to realize own palette ?
          I think you are supposed to forward the WM_QUERYNEWPALETTE, WM_PALETTECHANGED to child windows.

          From MSDN:
          The WM_QUERYNEWPALETTE message is sent to all top-level and overlapped windows; therefore, if any child window uses a color palette, this message must be passed on to it.



          ------------------
          Best Regards
          Peter Scheutz
          Best Regards
          Peter Scheutz

          Comment


          • #6
            Peter,

            When the sytem palette changes, you need to completely repaint your windows. I send an InvalidateRect( hwnd, byval %null ) to all my normal child windows - this way the WM_PAINT messages will be posted only when the messages queue is empty (no need to be in a hurry). The needed palette will be created inside the WM_PAINT processing code.

            I didn't try it, but with the dialog window may be it's enough to do the same. Windows uses this system to invalidate and update screen regions (e.g. when you move a foreground window over the other windows). In the case Semen stated, may be this is sufficient to make all his controlls redraw - the OWNERDRAW ones will be repainted with the needed palette.



            ------------------
            Rgds, Aldo

            Comment


            • #7
              Aldo--

              I was replying to:
              but where to realize own palette ?
              It seems better to only realize the palette when it changes, and not on every WM_PAINT event.

              As I read MSDN you can use SendMessage/PostMessage to forward the relevant palette messages to child windows.
              Then use the same type of palette handling code in your child window as for the main window.

              (I have not tested, so I'm not sure it works! )

              ------------------
              Best Regards
              Peter Scheutz

              [This message has been edited by Peter Scheutz (edited April 02, 2001).]
              Best Regards
              Peter Scheutz

              Comment


              • #8
                Peter,

                In my experience it is not sufficient to once create the palette for a window. I think this is because you create a palette into a Device Context, and all the DCs are transitory. I just added a flag to the program I'm working on (7500 and more lines...). I can switch this flag on/off at run-time to include/exclude the palette creation inside the WM_PAINT code; if you exlude that code, colors don't function any more.

                In a previous post I described a menu bar with owner-drawn items. The menu owner window has its own palette; if you omit to create the palette for the DC for THAT menu item, the colors are not shown correctly on the menu.

                The real problem is I couldn't find any good explanation on colors in API. May be the problem has a very simple solution, but I couldn't find it. All I know I've found by attempts...

                ------------------




                [This message has been edited by Aldo Cavini (edited April 02, 2001).]
                Rgds, Aldo

                Comment

                Working...
                X