Results 1 to 14 of 14

Thread: [VB6] - Custom rendering window.

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,797

    [VB6] - Custom rendering window.


    In Windows 7, there was a remarkable thing - indication of progress on the taskbar button. To use this feature on VB6 (and any other language) you need to create an object TaskBarList, get ITaskBarList3 interface and use its methods - SetProgressState and SetProgressValue. In my module, I added the ability to set the state of the progress bar on the taskbar, and duplicated this indicator on the form itself + added ability to use animated icons in the form header (also supported by the usual icons). From this example, you can learn how to draw the non-client area of the window, make buttons that are highlighted when hovering. The example uses double buffering, so everything works smoothly and without flicker. This module can be connected to any project with any forms.
    Functions:
    SetNCSkin - set new style window;
    RemoveNCSkin - remove style from window;
    SetIcon - set animated (or simple) icon to window;
    PlayAnimation - enable playing icon animation;
    StopAnimation - stop animation playing;
    SetProgressState - set state of taskbar button;
    GetProgressState - get state of taskbar button;
    SetProgressValue - set value of progressbar in the taskbar button (0..1);
    GetProgressValue - same, only get a value.

    Example use:
    Code:
    Option Explicit
     
    ' Тестовая форма модуля пользовательской отрисовки окна
    ' © Кривоус Анатолий Анатольевич (The trick), 2014
     
    Dim Value As Single
     
    Private Sub cboIcon_Click()
        Select Case cboIcon.ListIndex
        Case 0: SetIcon Me, LoadResPicture("TRICKICON", vbResBitmap), 21
        Case 1: SetIcon Me, LoadResPicture("WAITICON", vbResBitmap), 20
        End Select
    End Sub
     
    Private Sub cmdDuplicate_Click()
        Dim frm As frmTest
        Set frm = New frmTest
        frm.Show
    End Sub
     
    Private Sub cmdHideProgress_Click()
        SetProgressState Me, TBPF_NOPROGRESS
    End Sub
     
    Private Sub cmdIcon_Click()
        PlayAnimation Me, 32, False
    End Sub
    Private Sub cmdIconLoop_Click()
        PlayAnimation Me, 32, True
    End Sub
    Private Sub cmdProgress_Click()
        tmrTimer.Enabled = True
        Value = 0
    End Sub
    Private Sub cmdShowProgress_Click()
        If optState(0).Value Then SetProgressState Me, TBPF_NORMAL
        If optState(1).Value Then SetProgressState Me, TBPF_PAUSED
        If optState(2).Value Then SetProgressState Me, TBPF_ERROR
    End Sub
    Private Sub cmdStopAnimation_Click()
        StopAnimation Me
    End Sub
    Private Sub cmdStopProgress_Click()
        tmrTimer.Enabled = False
    End Sub
    Private Sub Form_Load()
        SetNCSkin Me
        cboIcon.ListIndex = 0
    End Sub
    Private Sub Form_Unload(Cancel As Integer)
        RemoveNCSkin Me
    End Sub
    Private Sub optState_Click(Index As Integer)
        Call cmdShowProgress_Click
    End Sub
     
    Private Sub tmrTimer_Timer()
        Value = Value + 0.01
        SetProgressValue Me, Value
    End Sub
    Attached Files Attached Files

  2. #2
    Fanatic Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    760

    Re: [VB6] - Custom rendering window.

    Thanks for sharing this. I'm considering different ways to display progress in my app and this looks interesting!

  3. #3

  4. #4
    Fanatic Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    760

    Re: [VB6] - Custom rendering window.

    Thanks for the link to the working project - I'll definitely check that out too. Not only for the progress bar code but for the music generation portion. I'm a musician and have a side app I've been working with slowly over the years - I may be able to borrow some ideas from you in that area as well.

  5. #5
    Fanatic Member
    Join Date
    Apr 2015
    Posts
    536

    Re: [VB6] - Custom rendering window.

    Problem getting it to work

    There is a reference to test.tlb.
    Test.tlb is not to find in the project folder.
    So I think I can select the Taskbar.tlb.

    It is checked in the references dialog.
    When I click OK, then this comes up:
    Microsoft Visual Basic - Error in loading DLL

    What do I miss?
    Thanks for a hint.

    (Win10/64, IDE manifested)
    Last edited by Karl77; Aug 7th, 2018 at 12:20 PM.

  6. #6
    Fanatic Member
    Join Date
    Apr 2015
    Posts
    536

    Re: [VB6] - Custom rendering window.

    Solved.

    The tlb failed to create a reference also in a new, empty project.

    I used the MIDL compiler to create a new tlb from the idl.
    Interestingly it has another GUID than the original, only the very last number.

    This new tlb loads fine, and with Custom rendering window as well.

  7. #7
    Addicted Member shagratt's Avatar
    Join Date
    Jul 2019
    Location
    Argentina
    Posts
    203

    Re: [VB6] - Custom rendering window.

    Hi The Trick, I found that Form_Resize is not being executed.
    I fixed changing WndProc with:

    Code:
        Case WM_SIZE
            WndProc = OnSize(hwnd, wParam, lParam And &HFFFF&, (lParam \ &H10000) And &HFFFF&)
            Call CallOldWndProc(hwnd, msg, wParam, lParam) ' <- Added line

  8. #8
    Addicted Member
    Join Date
    Jan 2008
    Posts
    203

    Re: [VB6] - Custom rendering window.

    Impossible reference to Taskbar.tlb

    If I convert the idl also not working... Y use Win 10 32 Bits, is possible this code is for 64Bits Windows?

  9. #9

  10. #10
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    Re: [VB6] - Custom rendering window.

    Very nice project...'

    I'm scratching my head trying to understand this though... you frequently use GetMem4 ByVal GetWindowLong(hwnd, GWL_USERDATA) + 34, stat

    This is used like it's referring to the ButtonState... but why is it seemingly taking 2 bytes of empty padding space and only the first two bytes of ButtonState?

    Code:
    Private Type AnimIcon
        Sequence As Long '12
        NumOfFrame As Long '16
        CurFrame As Long '20
        State As Long '24
        Interval As Long '28
        Looped As Boolean '32
        (padding, 2 bytes) '34
    End Type
    Private Type WndExtInfo
        lpOldWndProc As Long 'Ptr + 0
        ProgressValue As Single '4
        ProgressState As TaskbarLib.TBPFLAG '8
        Icon As AnimIcon
        ButtonsState As Long '36
    End Type
    And SetExtInfo is using CopyMemory ByVal pt, wi, Len(wi); when Len and LenB don't match; and

    GetMem4 ByVal GetWindowLong(hwnd, GWL_USERDATA) + 34, stat
    btnidx = GetBtnIndex(pos)
    stat = stat Or (&H100& * (btnidx + 1))
    GetMem4 stat, ByVal GetWindowLong(hwnd, GWL_USERDATA) + 34


    Given your skills I'm extremely hesitant to assume this is a bug; so is there another reason why the 2 bytes padding + 2 bytes ButtonsState, instead of +36 and just ButtonsState? I suppose it doesn't strictly matter as long as its consistent, but who knows when someone else will get confused and go looking

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,797

    Re: [VB6] - Custom rendering window.

    Quote Originally Posted by fafalone View Post
    Very nice project...'

    I'm scratching my head trying to understand this though... you frequently use GetMem4 ByVal GetWindowLong(hwnd, GWL_USERDATA) + 34, stat

    This is used like it's referring to the ButtonState... but why is it seemingly taking 2 bytes of empty padding space and only the first two bytes of ButtonState?

    Code:
    Private Type AnimIcon
        Sequence As Long '12
        NumOfFrame As Long '16
        CurFrame As Long '20
        State As Long '24
        Interval As Long '28
        Looped As Boolean '32
        (padding, 2 bytes) '34
    End Type
    Private Type WndExtInfo
        lpOldWndProc As Long 'Ptr + 0
        ProgressValue As Single '4
        ProgressState As TaskbarLib.TBPFLAG '8
        Icon As AnimIcon
        ButtonsState As Long '36
    End Type
    And SetExtInfo is using CopyMemory ByVal pt, wi, Len(wi); when Len and LenB don't match; and

    GetMem4 ByVal GetWindowLong(hwnd, GWL_USERDATA) + 34, stat
    btnidx = GetBtnIndex(pos)
    stat = stat Or (&H100& * (btnidx + 1))
    GetMem4 stat, ByVal GetWindowLong(hwnd, GWL_USERDATA) + 34


    Given your skills I'm extremely hesitant to assume this is a bug; so is there another reason why the 2 bytes padding + 2 bytes ButtonsState, instead of +36 and just ButtonsState? I suppose it doesn't strictly matter as long as its consistent, but who knows when someone else will get confused and go looking
    Yes this is the bug. Thank you for testing! When i used GetWindowLong(hwnd, GWL_USERDATA) + 34 i just read/write to the padding and part of ButtonsState member. Because of i don't access to ButtonsState directly using VB6 code so this bug doesn't affect to program behavior. Thank you for the test, you are very attentive

  12. #12
    Hyperactive Member
    Join Date
    May 2018
    Location
    Russia
    Posts
    343

    Question Re: [VB6] - Custom rendering window.

    Hi, The trick! Am I understand right that I can't use the Menu editor in this project? Or is there any workaround?

  13. #13

  14. #14
    Hyperactive Member
    Join Date
    May 2018
    Location
    Russia
    Posts
    343

    Re: [VB6] - Custom rendering window.

    Quote Originally Posted by The trick View Post
    It need to do additional steps to draw a menu because the menu is non-client area.
    It would be great! Especially if it becomes visual styled, not like in the days of Win98.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width