Announcement

Collapse
No announcement yet.

Skin support for plugin window controls

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

  • #16
    Originally Posted by Ingvar View Post
    Do you mean that if WM_DESTROY event occurs and we try to assign a window procedure that holds in memory of already unloaded at this time plugin, then an AV error will occurs?
    Potentially yes, it greatly depends on the order which Winamp unloads the various types of plugins during Winamp's shutdown/close. I've seen it before with my plugins.

    Originally Posted by Ingvar View Post
    On my last screenshot I overridden its WM_PAINT handler and did ownerdraw checkbox painting. Should it look different? How?
    I would think so, yes. How you do it is up to you since you would have to code it yourself like I had to for my plugins. You can also try just not using checkboxes and use toggle buttons or even combo boxes (which requires ML skinning support currently) that have native support. However, if you do it yourself, try to make them look like mine: http://forums.winamp.com/showpost.ph...1&postcount=63



    Originally Posted by Ingvar View Post
    It looks like there is skinning support for push buttons and scrollbar only.
    I used code to get skin HBITMAP and save it to file:
    code:
    SendMessage(plugin.hwndParent, WM_WA_IPC, 0, IPC_GET_GENSKINBITMAP);
    And skin HBITMAP contains this:


    As we can see, there glyphs for push-button and scrollbar are only.
    Yup.


    Originally Posted by Ingvar View Post
    By the way, where is this image stored? In what file? I looked through all the graphic and resources files in the Winamp folder but didn't find these glyphs.
    For modern skins there is no image store, I believe it's generated internally by Winamp based on the current color scheme of the selected modern skin, but that's a guess. For classic skins they exist inside the classic skin archive (or folder if it's not in an archive), I forgot the name of the file.


    Originally Posted by Ingvar View Post
    Ok, how to fix it to assign edit control skin support? How is it done in Jump to File plugin, for example?



    Here we can see specific themed borders at the bottom and right side of EDIT control. I tried to change the styles of the control, but I could not get such borders.

    Is the source code of Jump to File plugin available? I can't find it. I would be able to see the implementation of the edit control.
    As far as I know JTFE was never open source so the code is not available. It could be an incompatible resource style set on the edit control but I've never seen that before like that. I would suggest ripping the dialog resource out of JTFE and comparing the Style and Extended Style flags of the edit control itself for clues.
    | Opus Audio Codec plugins 2.0 | Embedded Album Art | DiskWrite |
    | Save your playlist first! | Live voice-over | X-Fade 2.5 |
    | AterKast (Source DSP) | More of my stuff... |

    Comment


    • #17
      Originally Posted by thinktink View Post
      You can also try just not using checkboxes
      Why?
      Originally Posted by thinktink View Post
      use toggle buttons
      What is the toggle buttons?
      Originally Posted by thinktink View Post
      As far as I know JTFE was never open source so the code is not available. It could be an incompatible resource style set on the edit control
      I have looked at the resources in gen_jumpex.dll file. But there is no such dialog. It looks like it is created dynamically using CreateWindow(). But Spy++ shows these styles:
      Class Name: Edit

      WS_CHILDWINDOW
      WS_VISIBLE
      WS_TABSTOP
      ES_LEFT
      ES_AUTHOHSCROLL

      WS_EX_LEFT
      WS_EX_LTRREADING
      WS_EX_RIGHTSCROLLBAR
      WS_EX_NOPARENTNOTIFY
      I created an edit control with the same styles:
      code:
      CreateWindowEx(WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOPARENTNOTIFY, L"EDIT", L"Edit control", WS_CHILDWINDOW | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 20, 20, 75, 28, hwnd, NULL, plugin.hDllInstance, NULL);
      But it doesn't look like it in Jump to File window:



      As you can see there is no bottom and right side borders.

      I also noticed that button with BS_OWNERDRAW style flickers when switching between the plugin window and the main window and back.
      I also have set the WS_CLIPSIBLINGS and WS_CLIPCHILDREN styles for the button's parent window (i.e. for the dialog).

      But with this:
      code:
      case WM_DRAWITEM:
      {
      DRAWITEMSTRUCT *di = (DRAWITEMSTRUCT *)lParam;
      FillRect(di->hDC, &di->rcItem, blue_brush);
      return true;
      }

      or with this:
      code:
      case WM_DRAWITEM:
      {
      return WADlg_handleDialogMsgs(hwnd, msg, wParam, lParam);
      }

      button flickers:



      However, in the JTF plugin window, the buttons do not blink! However, despite the fact that JTF's buttons have BS_OWNERDRAW style, their parent window (dialog) does not receive WM_DRAWITEM message (I see it in Spy++). But why??
      According to documentation:
      for BS_OWNERDRAW style: The owner window receives a WM_DRAWITEM message when a visual aspect of the button has changed
      Nonetheless, how to get rid of the flickering of the ownerdraw buttons?

      Comment


      • #18
        Ok, so how do I get or calculate the text color for an inactive button?

        For example, for a Bento skin the inactive text color should be: 91, 94, 95:
        And for Winamp Modern Skin - 147, 149, 155

        I checked all colors that WADlg_getColor() function returns. There is no such colors! Also I checked the contents of the skin bitmap (IPC_GET_GENSKINBITMAP). There is no such colors also.

        It's like the text color for an inactive button is calculated by some formula.

        I found the formula inside wa_dlg.h file:
        PHP Code:
        fg wadlg_colors[WADLG_WNDFG];
        bg wadlg_colors[WADLG_WNDBG];
        colour RGB((GetRValue(fg)+GetRValue(bg))/2, (GetGValue(fg)+GetGValue(bg))/2, (GetBValue(fg)+GetBValue(bg))/2); 
        But this calculation gives wrong color. For example, for Bento:

        fg = 210, 210, 210
        bg = 51, 55, 56
        colour = (210+51)/2, (210+55)/2, (210+56)/2 = 130, 132, 133

        When DrawText() with this color, then we will see:



        Similarly for Winamp Modern:

        fg = 255, 255, 255
        bg = 127, 135, 149
        colour = (255+127)/2, (255+135)/2, (255+149)/2 = 191, 195, 202

        When DrawText() with this color, then we will see:



        As you can see, this is an incorrect calculation formula.

        For example in JTF plugin inactive buttons has the correct text color.


        So how do you calculate the correct color values for inactive text?

        Comment


        • #19
          I'm working on an unauthorized update to the example plugin originally created by DrO with skinned controls and menus. It should answer a number of questions. Just need a little time.
          | Opus Audio Codec plugins 2.0 | Embedded Album Art | DiskWrite |
          | Save your playlist first! | Live voice-over | X-Fade 2.5 |
          | AterKast (Source DSP) | More of my stuff... |

          Comment


          • #21
            Despite some errors in your code, the principle of skinning the controls is clear.

            In short, in order to skin the controls, the developer needs to either draw them completely (owner drawing) or use a wrapper functions from wa_dlg.h, or request the API of the media library plugin to perform the skinning of the controls.

            I also noticed that when using Media library API you must also use the WADlg_DrawChildWindowBorders() function for drawing borders, because Media library API does not draw it. It's strange that drawing borders is not part of skinning support of the Media library API.

            To perform skinning of the edit control, I tried to use the media library API:

            PHP Code:
            //on WM_INITDIALOG
            MLSKINWINDOW mlsw = {0};
            mlsw.hwndToSkin GetDlgItem(hwndIDC_EDIT1);
            mlsw.skinType SKINNEDWND_TYPE_EDIT;
            mlsw.style SWS_USESKINCOLORS SWS_USESKINCURSORS SWS_USESKINFONT;
            MLSkinWindow(ML_hWnd, &mlsw);

            //on WM_PAINT draw borders (because ML API doesn't support it)
            WADlg_DrawChildWindowBorders(...) 
            And it works well except that it keeps using the default font and not the skin font.
            As you can see the required bit SWS_USESKINFONT is set.



            The only way to set the correct font for an edit control is to create a font and set it with WM_SETFONT for Edit control and not set SWS_USESKINFONT bit in mlsw.style.

            I just don't understand why SWS_USESKINFONT bit doesn't work.

            Comment


            • #22
              Originally Posted by Ingvar View Post
              Despite some errors in your code...
              If you can, please mark the errors so that I can correct them.
              | Opus Audio Codec plugins 2.0 | Embedded Album Art | DiskWrite |
              | Save your playlist first! | Live voice-over | X-Fade 2.5 |
              | AterKast (Source DSP) | More of my stuff... |

              Comment


              • #23
                Originally Posted by thinktink View Post
                please mark the errors
                I tested your plugin (embedded window) and found that WADlg_DrawChildWindowBorders() function draws wrong borders for edit control. It draws one extra pixel:



                To fix this I changed the WADlg_DrawChildWindowBorders() function code a bit:

                PHP Code:
                if((0xffff0000) == DCW_SUNKENBORDER)
                {
                MoveToEx(ps->hdcr.leftr.bottomNULL);
                LineTo(ps->hdcr.rightr.bottom);
                MoveToEx(ps->hdcr.rightr.bottom 1NULL);
                LineTo(ps->hdcr.rightr.top 1); 
                WADlg_DrawChildWindowBorders() function cannot be used in WM_PAINT handler when in WM_PAINT already has some kind of drawing defined. Because the WADlg_DrawChildWindowBorders() is re-calling BeginPaint() function, it returns an empty HDC.
                For my purposes I have fixed it.

                Also when switching the focus between winamp windows, the edit control's borders are flickers.

                Combobox cannot have a style CBS_DROPDOWNLIST because winamp doesn't skin the combobox's button.
                It should be set CBS_DROPDOWN style instead.

                PHP Code:
                embedwnd.cpp file:
                //line 233
                HWND mlwnd=NULL;

                if(!
                IsWindow(mlwnd)) 
                Here IsWindow() always takes NULL.

                Comment


                • #24
                  Version 1.3 (unauthorized) now available.

                  Changes:
                  • Fixed always NULL condition as indicated by Ingvar in the ML window handle retrieval function: http://forums.winamp.com/showthread....32#post3227532
                  • Updated reskin/refresh code to get consistent and expected results
                  • Added "CreateSkinFont" function to load/reload the current skin's font
                  • WM_SETFONT on every text displaying/handling control due to oddities
                  • Added posting of WM_DISPLAYCHANGE during WM_INITDIALOG due to oddities
                  • Added WM_APP handler to refresh certain aspects after skin switching completed as it wasn't working correctly all inside WM_DISPLAYCHANGE


                  Attached.
                  Attached Files
                  | Opus Audio Codec plugins 2.0 | Embedded Album Art | DiskWrite |
                  | Save your playlist first! | Live voice-over | X-Fade 2.5 |
                  | AterKast (Source DSP) | More of my stuff... |

                  Comment


                  • #25
                    Originally Posted by Ingvar View Post
                    I tested your plugin (embedded window) and found that WADlg_DrawChildWindowBorders() function draws wrong borders for edit control. It draws one extra pixel:

                    ...
                    It's not my function, it's part of the SDK, I can't change the SDK. To be honest, I'm not sure that's actually an error.


                    Originally Posted by Ingvar View Post
                    Also when switching the focus between winamp windows, the edit control's borders are flickers.
                    I don't doubt that this is an issue for you, unfortunately I've not been able to replicate it to test.


                    Originally Posted by Ingvar View Post
                    Combobox cannot have a style CBS_DROPDOWNLIST because winamp doesn't skin the combobox's button.
                    It should be set CBS_DROPDOWN style instead.
                    It seems to be working with CBS_DROPDOWNLIST fine for me, button and everything. Works on Windows 10 and Windows XP running inside Oracle VM VirtualBox.


                    Originally Posted by Ingvar View Post
                    PHP Code:
                    embedwnd.cpp file:
                    //line 233
                    HWND mlwnd=NULL;

                    if(!
                    IsWindow(mlwnd)) 
                    Here IsWindow() always takes NULL.
                    Fixed in version 1.3. Thank you.
                    | Opus Audio Codec plugins 2.0 | Embedded Album Art | DiskWrite |
                    | Save your playlist first! | Live voice-over | X-Fade 2.5 |
                    | AterKast (Source DSP) | More of my stuff... |

                    Comment

                    Working...
                    X
                    😀
                    🥰
                    🤢
                    😎
                    😡
                    👍
                    👎