Page 1 of 2 12 LastLast
Results 1 to 40 of 44

Thread: Unicode caption for form: not working with classic or non-themed mode

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Unhappy Unicode caption for form: not working with classic or non-themed mode

    Hi, I've tried most method that I found on the internet but no lucky to set a Unicode title on Window Server. This is how the application look like on Window Server:

    Name:  unicode-form-caption-vb6.jpg
Views: 875
Size:  13.4 KB

    VB.NET Code so simply:

    Code:
      Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            Me.Text = ChrW(1088) & ChrW(1089) & ChrW(1090) & ChrW(1091)
        End Sub
    VB6 Code - not working for Window Server 2008 or classic or non-themed mode:

    Code:
    Option Explicit
    Private Declare Function GetModuleHandleW Lib "kernel32" (ByVal lpModuleName As Long) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private Declare Function GetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function SetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function SetWindowLongW Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function SetWindowTextW Lib "user32" (ByVal hWnd As Long, ByVal lpString As Long) As Long
    Private Const GWL_WNDPROC = -4
    Private m_Caption As String
    
    Public Property Get CaptionW() As String
    CaptionW = m_Caption
    End Property
    
    Public Property Let CaptionW(ByRef NewValue As String)
    Static WndProc As Long, VBWndProc As Long
    m_Caption = NewValue
    ' get window procedures if we don't have them
    If WndProc = 0 Then
    ' the default Unicode window procedure
    WndProc = GetProcAddress(GetModuleHandleW(StrPtr("user32")), "DefWindowProcW")
    ' window procedure of this form
    VBWndProc = GetWindowLongA(hWnd, GWL_WNDPROC)
    End If
    ' ensure we got them
    If WndProc <> 0 Then
    ' replace form's window procedure with the default Unicode one
    SetWindowLongW hWnd, GWL_WNDPROC, WndProc
    ' change form's caption
    SetWindowTextW hWnd, StrPtr(m_Caption)
    ' restore the original window procedure
    SetWindowLongA hWnd, GWL_WNDPROC, VBWndProc
    Else
    ' no Unicode for us
    Caption = m_Caption
    End If
    End Property
    
    ' usage sample
    Private Sub Form_Load()
    '??????? ????? ?? ????? ???? ? ??????
    CaptionW = ChrW$(1088) & ChrW$(1089) & ChrW$(1090) & ChrW$(1091)
    End Sub

    Anyone know how to fix this issue? Thank you all a lot
    Last edited by vietnamvodich; Dec 28th, 2017 at 03:22 AM.

  2. #2
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Unicode caption for form: not working with classic or non-themed mode

    The version below is less "noisy" and does it for me (with your Unicode-Input) -
    (it's also less risky, by simply avoiding all that WindowProc-Pointer-Swapping):

    Code:
    Option Explicit
     
    Private Declare Function DefWindowProcW& Lib "user32" (ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
    
    Public Property Get CaptionW() As String
      Const WM_GETTEXT = &HD
      CaptionW = Space$(2048)
      CaptionW = Left$(CaptionW, DefWindowProcW(hWnd, WM_GETTEXT, Len(CaptionW), StrPtr(CaptionW)))
    End Property
    Public Property Let CaptionW(ByVal RHS As String)
      Const WM_SETTEXT = &HC
      DefWindowProcW hWnd, WM_SETTEXT, Len(RHS), StrPtr(RHS)
    End Property
     
    Private Sub Form_Load()
      CaptionW = ChrW$(1088) & ChrW$(1089) & ChrW$(1090) & ChrW$(1091)
      Debug.Print CaptionW = ChrW$(1088) & ChrW$(1089) & ChrW$(1090) & ChrW$(1091)
    End Sub
    HTH

    Olaf

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Schmidt View Post
    The version below is less "noisy" and does it for me (with your Unicode-Input) -
    (it's also less risky, by simply avoiding all that WindowProc-Pointer-Swapping):

    Code:
    Option Explicit
     
    Private Declare Function DefWindowProcW& Lib "user32" (ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
    
    Public Property Get CaptionW() As String
      Const WM_GETTEXT = &HD
      CaptionW = Space$(2048)
      CaptionW = Left$(CaptionW, DefWindowProcW(hWnd, WM_GETTEXT, Len(CaptionW), StrPtr(CaptionW)))
    End Property
    Public Property Let CaptionW(ByVal RHS As String)
      Const WM_SETTEXT = &HC
      DefWindowProcW hWnd, WM_SETTEXT, Len(RHS), StrPtr(RHS)
    End Property
     
    Private Sub Form_Load()
      CaptionW = ChrW$(1088) & ChrW$(1089) & ChrW$(1090) & ChrW$(1091)
      Debug.Print CaptionW = ChrW$(1088) & ChrW$(1089) & ChrW$(1090) & ChrW$(1091)
    End Sub
    HTH

    Olaf
    Hi Schmidt, i've tried it too. Yes it does work on Windows 7/8/10 with theme enabled. But try to run your app on Window Server or switch to Classic Theme (on Windows 7). You will see this:

    Name:  unicodetitle.png
Views: 739
Size:  939 Bytes

  4. #4
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by vietnamvodich View Post
    Yes it does work on Windows 7/8/10 with theme enabled. But try to run your app on Window Server or switch to Classic Theme (on Windows 7).
    Could reproduce it on an older XP-VM (which did not have a Theme enabled).

    But... since the second line in Form-Load (on my old,"classic GUI" XP-Machine):
    Code:
    Debug.Print CaptionW = ChrW$(1088) & ChrW$(1089) & ChrW$(1090) & ChrW$(1091)
    ...*did* Print out a True, the Form-hWnd in question obviously did receive (and now holds) the correct Unicode-WindowText.

    That the Caption is nevertheless rendered with question-marks, has in *this* case nothing to do with ANSIText-Caption-Characters,
    but with an inappropriate (different) Font-Selection, which VB6-ANSI-Forms make for their NC-Area-renderings, in case they start up "un-themed".
    Edit: the above part (marked in red) was a wrong assumption - the culprit in this case is the ANSI-Default-Handler for WM_NCPAINT, which
    in the unthemed-case does use a GetWindowTextA + TextOutA (respectively DrawTextA) on the hWnd in question, whilst in themed mode
    does a fallback to GetWindowTextW + uxTheme.DrawText)


    There is not much you can do in this case I guess, other than switching to a Form-Engine which works with Unicode throughout (already in the Startup-Phase).

    The RC5-FormEngine is fully Unicode-aware and does (like a :NET-Form) show the Caption correctly, also on my old XP-VM:
    (in case you want to try it - make sure, that your Project contains a reference to vbRichClient5 and only a *.bas-Module)
    Code:
    Sub Main()
      Dim Form As cWidgetForm
      Set Form = Cairo.WidgetForms.Create(vbSizable)
          Form.Caption = ChrW(1088) & ChrW(1089) & ChrW(1090) & ChrW(1091) '<- this UniCode-Caption works as it should, also on an unthemed XP
          Form.Show
          
      Cairo.WidgetForms.EnterMessageLoop
    End Sub
    Olaf
    Last edited by Schmidt; Dec 28th, 2017 at 08:58 PM.

  5. #5
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: Unicode caption for form: not working with classic or non-themed mode

    i tested the code in post #2 on xp displayed the unicode
    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by westconn1 View Post
    i tested the code in post #2 on xp displayed the unicode
    Hi westconn1 , try this :
    Name:  classic-style.png
Views: 793
Size:  25.2 KB


    It's lucky that this issue does not occur on Windows Server 2012 by default.
    But still many people using Windows Server 2008 and it's a bit hurt.

    @Schmidt:
    Thank you very much for this information. I just take a look at RC5 Form engine. It's seems too much complicated to switch my project to using RC5 form engine just for fix this issue

    Anyone have any other ideas? Should I do a patch on VBVM , any idea would be appreciate ...

  7. #7
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Unicode caption for form: not working with classic or non-themed mode

    Isn't that a restriction with DefWindowProcW?

    Per Dr. Unicode in this thread
    AFAIK DefWindowProcW solution will only work when Windows is Themed.
    If you switch to Classic Theme or are using version of Windows that has no Themes then you have to subclass the TitleBar and draw it yourself.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  8. #8
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,728

    Re: Unicode caption for form: not working with classic or non-themed mode

    I can remember that for classic theme to support unicode you need to subclass the form and catch WM_NCPAINT and pass it to DefWindowProcW.

  9. #9
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by LaVolpe View Post
    Isn't that a restriction with DefWindowProcW?
    DefWindowProcW is just "a more direct SendMessageW-replacement" (which bypasses the current WinProc-Handler) -
    and as already reported, the Unicode-Caption is "landed" just fine per WM_SETTEXT in the hWnd in question
    (since it can be successfully retrieved in Unicode-Format per WM_GETTEXT as well).

    As Krool was mentioning, it is the WM_NCPaint-message which is finally responsible for the rendering
    of that now successfully placed W-String-Caption.

    In case of a "themed Desktop", the Default-NCPaint-Handler of an ANSI-Window has no other choice than to feed
    the existing Caption-String as a W-String to the uxTheme.dll-routines (which support only WStrings - and have no A-API-exports).

    If it is unthemed, then apparently normal "DrawTextA" (GetWindowTextA) will be applied by the default-handler of NCPaint (in an ANSI-Window).

    So I guess SubClassing is indeed the only solution for VB6-ANSI-Windows in an un-themed setting
    (not sure whether SetWindowTheme(..) would help on the ANSI-hWnd in question, to avoid the SubClassing).

    Olaf

  10. #10
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Schmidt View Post
    DefWindowProcW is just "a more direct SendMessageW-replacement" (which bypasses the current WinProc-Handler) -
    and as already reported, the Unicode-Caption is "landed" just fine per WM_SETTEXT in the hWnd in question
    (since it can be successfully retrieved in Unicode-Format per WM_GETTEXT as well).

    As Krool was mentioning, it is the WM_NCPaint-message which is finally responsible for the rendering
    of that now successfully placed W-String-Caption.
    Probably could have worded my response so people didn't have to review the thread I linked to, but the gist is rather simple: If themed, DefWindowProcW can be used else DefWindowProcA typically applies for VB forms. And DefWindowProcA doesn't do unicode.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  11. #11
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by LaVolpe View Post
    Probably could have worded my response so people didn't have to review the thread I linked to, but the gist is rather simple: If themed, DefWindowProcW can be used else DefWindowProcA typically applies for VB forms. And DefWindowProcA doesn't do unicode.
    What my reply was meant to say is, that DefWindowProcA (in case of WM_NCPAINT) apparently *does* handle Unicode
    for that specific message (when themed), as long as the Window-Caption was placed on the hWnd as a W-String beforehand
    (no matter if that "W-Caption-placement" happened per DefWindowProcW or SendMessageW or SetWindowTextW).

    The problem has "two stages" (two hurdles to take) - solving the first one successfully is not sufficient for the "second stage" (in an un-themed OS-setting).

    Olaf

  12. #12
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Unicode caption for form: not working with classic or non-themed mode

    These are the procedures I've used for quite some time, and they work on both forms and controls. Also, I don't have anything about themes in the manifest of my primary application.

    Also, make them public and throw them into a BAS module if you'd like to use them everywhere.

    Code:
    
    Option Explicit
    '
    Private Declare Function DefWindowProcW Lib "user32.dll" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function GetClientRect Lib "user32.dll" (ByVal hWnd As Long, lpRect As RECT) As Long
    Private Declare Function InvalidateRect Lib "user32.dll" (ByVal hWnd As Long, lpRect As RECT, ByVal bErase As Long) As Long
    Private Declare Function SysAllocStringLen Lib "oleaut32.dll" (ByVal OleStr As Long, ByVal bLen As Long) As Long
    Private Declare Sub PutMem4 Lib "msvbvm60.dll" (ByRef Ptr As Any, ByRef Value As Any)
    '
    Private Type RECT
        Left   As Long
        Top    As Long
        Right  As Long ' This is +1 (right - left = width)
        Bottom As Long ' This is +1 (bottom - top = height)
    End Type
    
    Private Sub Form_Load()
    
    
        Dim s As String
        s = ChrW$(1255)
        SetUniCaption Me.hWnd, s
    
    
    
    End Sub
    
    
    Private Sub SetUniCaption(TheHwnd As Long, sUniCaption As String)
        ' Set Unicode string into the caption.
        '
        Dim uRect As RECT
        Const WM_SETTEXT As Long = &HC
        DefWindowProcW TheHwnd, WM_SETTEXT, 0&, ByVal StrPtr(sUniCaption)
        GetClientRect TheHwnd, uRect
        InvalidateRect TheHwnd, uRect, 1&
    End Sub
    
    Private Function GetUniCaption(TheHwnd As Long) As String
        ' Get Unicode string from caption.
        '
        Const WM_GETTEXT As Long = &HD
        Const WM_GETTEXTLENGTH As Long = &HE
        Dim lLen As Long
        Dim lPtr As Long
        lLen = DefWindowProcW(TheHwnd, WM_GETTEXTLENGTH, 0&, ByVal 0&)  ' Get length of caption.
        If lLen Then ' Must have length.
            lPtr = SysAllocStringLen(0&, lLen)                          ' Create a BSTR of that length.
            PutMem4 ByVal VarPtr(GetUniCaption), ByVal lPtr             ' Make the property return the BSTR.
            DefWindowProcW TheHwnd, WM_GETTEXT, lLen + 1&, ByVal lPtr   ' Call the default Unicode window procedure to fill the BSTR.
        End If
    End Function
    
    Enjoy,
    Elroy


    EDIT1: And since I'm looking at these things, I decided to rework them into properties. I think it's a bit cleaner that way:

    Code:
    
    Option Explicit
    '
    Private Declare Function DefWindowProcW Lib "user32.dll" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function GetClientRect Lib "user32.dll" (ByVal hWnd As Long, lpRect As RECT) As Long
    Private Declare Function InvalidateRect Lib "user32.dll" (ByVal hWnd As Long, lpRect As RECT, ByVal bErase As Long) As Long
    Private Declare Function SysAllocStringLen Lib "oleaut32.dll" (ByVal OleStr As Long, ByVal bLen As Long) As Long
    Private Declare Sub PutMem4 Lib "msvbvm60.dll" (ByRef Ptr As Any, ByRef Value As Any)
    '
    Private Type RECT
        Left   As Long
        Top    As Long
        Right  As Long ' This is +1 (right - left = width)
        Bottom As Long ' This is +1 (bottom - top = height)
    End Type
    
    Private Sub Form_Load()
    
    
        Dim s As String
        s = ChrW$(1255)
        UniCaption(Me.hWnd) = s
    
    
    
    End Sub
    
    
    Private Property Let UniCaption(TheHwnd As Long, sUniCaption As String)
        ' Set Unicode string into the caption.
        '
        Dim uRect As RECT
        Const WM_SETTEXT As Long = &HC
        DefWindowProcW TheHwnd, WM_SETTEXT, 0&, ByVal StrPtr(sUniCaption)
        GetClientRect TheHwnd, uRect
        InvalidateRect TheHwnd, uRect, 1&
    End Property
    
    Private Property Get UniCaption(TheHwnd As Long) As String
        ' Get Unicode string from caption.
        '
        Const WM_GETTEXT As Long = &HD
        Const WM_GETTEXTLENGTH As Long = &HE
        Dim lLen As Long
        Dim lPtr As Long
        lLen = DefWindowProcW(TheHwnd, WM_GETTEXTLENGTH, 0&, ByVal 0&)  ' Get length of caption.
        If lLen Then ' Must have length.
            lPtr = SysAllocStringLen(0&, lLen)                          ' Create a BSTR of that length.
            PutMem4 ByVal VarPtr(UniCaption), ByVal lPtr                ' Make the property return the BSTR.
            DefWindowProcW TheHwnd, WM_GETTEXT, lLen + 1&, ByVal lPtr   ' Call the default Unicode window procedure to fill the BSTR.
        End If
    End Property
    
    Last edited by Elroy; Dec 28th, 2017 at 01:56 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  13. #13
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Unicode caption for form: not working with classic or non-themed mode

    @Elroy. Your code is nearly identical to Olaf's posted back in #2 above, which did not work in a specific case.

    Regarding themes, this topic has nothing to do with manifesting for theming controls, but rather the Windows option to use window themes, i.e., aero, lumina, etc vs unthemed (classic). Note. Not sure you can opt for classic themes after Win7.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  14. #14
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Unicode caption for form: not working with classic or non-themed mode

    @LaVolpe: Hmmm, ok. And yeah, I saw that Olaf had posted similar code. I also noticed that mine had a call to InvalidateRect in it. I truly don't remember why that's there, but I'm certain it's needed in certain circumstances or I wouldn't have placed it there. I'm wondering if that'll make a difference for the "classic theme" that you're struggling with, as I've certainly been using this code on machines using OS's before Win7 (i.e., Vista and even XP). It would be difficult for me to test at this point (as I've got no readily accessible computers with OS's earlier than Win7).

    @vietnamvodich: Good Luck.

    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  15. #15
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Unicode caption for form: not working with classic or non-themed mode

    As far as I can tell InvalidateRect() does nothing outside of the window's client area anyway.

  16. #16
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Unicode caption for form: not working with classic or non-themed mode

    Hmmm, yeah, I just read the MSDN article on it. I just have a vague memory of struggling to get what I wanted from those procedures (as it's been a few years back). It may have had to do with controls (such as option buttons or others) where the caption is part of the client area. If that's the case, then that certainly won't help with the "classic themes" problem.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  17. #17
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Schmidt View Post
    That the Caption is nevertheless rendered with question-marks, has in *this* case nothing to do with ANSIText-Caption-Characters, but with an inappropriate (different) Font-Selection, which VB6-ANSI-Forms make for their NC-Area-renderings, in case they start up "un-themed".
    I doubt this is a factor since the caption font is a system-level setting. See NONCLIENTMETRICS.

  18. #18
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by dilettante View Post
    I doubt this is a factor since the caption font is a system-level setting. See NONCLIENTMETRICS.
    Yep - ANSI-Forms do not select different Fonts at creation- (or upstart-) time
    (should have edited my comment after Krool hinted at the Default-ANSI-WM_NCPAINT - Handler,
    which does a GetWindowTextW on the hWnd in question *only* in case it wants to render using Exports from uxTheme.dll).

    Olaf

  19. #19

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    Hi there!
    Thank you all for reply on my thread.
    I've spent a day to struggling for this issue. I can now create a vb6 form with unicode title by register my own Unicode class with RegisterClassW and hook/patch the MSVBVM60.dll to use the class I registered. But all event on the form seems not firing ( I clicked on the button and nothing happen).

    Here is how I do it. First create my own class using RegisterClassW (i just copied an example from the internet) :

    Code:
    Option Explicit
                   
    Declare Function LoadIconW Lib "user32.dll" _
            (ByVal a As Long, ByVal b As Long) As Long
    Declare Function LoadCursorW Lib "user32.dll" _
            (ByVal a As Long, ByVal b As Long) As Long
    Declare Function GetStockObject Lib "gdi32.dll" _
            (ByVal a As Long) As Long
    Declare Function RegisterClassW Lib "user32.dll" (ByVal a As Long) As Long
    Declare Function CreateWindowExW Lib "user32.dll" _
            (ByVal a As Long, ByVal b As Long, ByVal c As Long, ByVal d As Long, _
            ByVal e As Long, ByVal f As Long, ByVal g As Long, ByVal h As Long, _
            ByVal i As Long, ByVal j As Long, ByVal k As Long, ByVal l As Long) _
            As Long
    Declare Function ShowWindow Lib "user32.dll" _
            (ByVal a As Long, ByVal b As Long) As Long
    Declare Function UpdateWindow Lib "user32.dll" (ByVal a As Long) As Long
    Declare Function GetMessageW Lib "user32.dll" _
            (ByVal a As Long, ByVal b As Long, ByVal c As Long, ByVal d As Long) _
            As Long
    Declare Function TranslateMessage Lib "user32.dll" (ByVal a As Long) As Long
    Declare Function DispatchMessageW Lib "user32.dll" (ByVal a As Long) As Long
    Declare Function PostQuitMessage Lib "user32.dll" (ByVal a As Long) As Long
    Declare Function DefWindowProcW Lib "user32.dll" _
            (ByVal a As Long, ByVal b As Long, ByVal c As Long, ByVal d As Long) _
            As Long
    Declare Function MoveWindow Lib "user32.dll" _
            (ByVal a As Long, ByVal b As Long, ByVal c As Long, _
            ByVal d As Long, ByVal e As Long, ByVal f As Long) As Long
    Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" _
            (ByVal dst As Long, ByVal src As Long, ByVal length As Long)
                   
    Type WNDCLASSW
        style As Long
        lpfnWndProc As Long
        cbClsExtra As Long
        cbWndExtra As Long
        hInstance As Long
        hIcon As Long
        hCursor As Long
        hbrBackground As Long
        lpszMenuName As Long
        lpszClassName As Long
    End Type
                   
    Type MSG
        hwnd As Long
        message As Long
        wParam As Long
        lParam As Long
        time As Long
        pt_x As Long
        pt_y As Long
    End Type
                   
    Type POINTS
        x As Integer
        y As Integer
    End Type
                   
    Public strClassName As String
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Program starts here
                   
    Function GetAddr(ByVal a As Long) As Long
        GetAddr = a
    End Function
                   
    Function MakePOINTS(ByVal l As Long) As POINTS
        CopyMemory VarPtr(MakePOINTS), VarPtr(l), 4
    End Function
                   
    Public Function WndProc(ByVal hwnd As Long, ByVal message As Long, _
                            ByVal wParam As Long, ByVal lParam As Long) As Long
        Static hEdit As Long
        Select Case message
        Case 5 ' WM_SIZE
            Dim ps As POINTS
            ps = MakePOINTS(lParam)
            MoveWindow hEdit, 10, 10, ps.x - 20, ps.y - 20, 1
            WndProc = 0
        Case 2 ' WM_DESTROY
            PostQuitMessage 0
            WndProc = 0
        Case Else
            WndProc = DefWindowProcW(hwnd, message, wParam, lParam)
        End Select
    End Function
                   
    Sub Main()
    strClassName = "MyVbClass"
    Dim retn As Long
        Dim wc As WNDCLASSW
        wc.style = 3 ' CS_HREDRAW | CS_VREDRAW
        wc.lpfnWndProc = GetAddr(AddressOf WndProc)
        wc.hIcon = LoadIconW(0, 32512)  'IDI_APPLICATION
        wc.hCursor = LoadCursorW(0, 32512) ' IDC_ARROW
        wc.hbrBackground = GetStockObject(0) ' WHITE_BRUSH
        wc.lpszClassName = StrPtr(strClassName)
      retn = RegisterClassW(VarPtr(wc))
    MsgBox Hex(StrPtr(strClassName))  '  WE GOT THE UNICODE STRING POINER HERE FOR THE NEXT STEP
    Form1.Show
    End Sub

    Now compile the App and debug with OllyDBG. Press F9 to Run. You will see a messagebox like this
    ---------------------------
    Project1
    ---------------------------
    588B74
    ---------------------------
    OK
    ---------------------------
    Press Ctrl+G to goto address 6605A65B ( 66000000 is the base address of MSVBVM60.dll on my computer so you need to change it depend on your computer) . Put a break point at 6605A65B .


    Code:
    6605A640   50               PUSH EAX
    6605A641   FF75 FC          PUSH DWORD PTR SS:[EBP-4]
    6605A644   FF75 E8          PUSH DWORD PTR SS:[EBP-18]
    6605A647   FF75 EC          PUSH DWORD PTR SS:[EBP-14]
    6605A64A   FF75 F8          PUSH DWORD PTR SS:[EBP-8]
    6605A64D   53               PUSH EBX
    6605A64E   FF75 08          PUSH DWORD PTR SS:[EBP+8]
    6605A651   FFB6 84000000    PUSH DWORD PTR DS:[ESI+84]
    6605A657   57               PUSH EDI
    6605A658   FF75 F4          PUSH DWORD PTR SS:[EBP-C]
    6605A65B   FF15 F0140066    CALL DWORD PTR DS:[<&USER32.CreateWindowExA>]                                        ; call 763C2D10
    -> patch here to convert to CreateWindowExW
    Press Ok and the app pause at the breakpoint.
    Edit the code at 6605A65B to make it become : Call CreateWindowExW
    Edit the stack variables:
    Edit 0019F968 and 0019F96C to 00588B74 ( 00588B74 is the pointer we got from the message box - it's point to "MyVbClass" ). So here is the final parameters it passed to CreateWindowExW:

    Code:
    0019F964   00040000  |ExtStyle = WS_EX_APPWINDOW
    0019F968   00588B74  |Class = "MyVbClass"
    0019F96C   00588B74  |WindowName = "MyVbClass"
    0019F970   02CF0000  |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_CLIPCHILDREN|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION
    0019F974   80000000  |X = 80000000 (-2147483648.)
    0019F978   80000000  |Y = 80000000 (-2147483648.)
    0019F97C   00000148  |Width = 148 (328.)
    0019F980   000000F8  |Height = F8 (248.)
    0019F984   00B52346  |hParent = 00B52346 ('Project1',class='ThunderRT6Main')
    0019F988   00000000  |hMenu = NULL
    0019F98C   00000000  |hInst = NULL
    0019F990   00000000  \lParam = NULL

    Now press F9 again and you will see the form, it's now able to create a Unicode title because it's created by RegisterClassW and CreateWindowExW . But I don't know why the button not working


    Name:  stupid.png
Views: 702
Size:  2.1 KB
    Last edited by vietnamvodich; Dec 28th, 2017 at 11:17 PM.

  20. #20
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,728

    Re: Unicode caption for form: not working with classic or non-themed mode

    Overkill..

    Just subclass the form. Catch WM_NCPAINT and pass to DefWindowProcW. Solved.

    Of course you need the other tips of placing a W-String via WM_SETTEXT.

  21. #21

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Krool View Post
    Overkill..

    Just subclass the form. Catch WM_NCPAINT and pass to DefWindowProcW. Solved.

    Of course you need the other tips of placing a W-String via WM_SETTEXT.
    Hi Krool, i can't make it work. Could you please tell me what I'm wrong? Here is my subclass :

    Code:
    Private Sub WndProc(ByVal bBefore As Boolean, _
           ByRef bHandled As Boolean, _
           ByRef lReturn As Long, _
           ByVal hwnd As Long, _
           ByVal uMsg As Long, _
           ByVal wParam As Long, _
           ByVal lParam As Long, _
           ByRef lParamUser As Long)
    
    If uMsg = WM_NCPAINT Then
     bHandled = True
     lReturn = DefWindowProcW(hwnd, uMsg, wParam, lParam)
     Exit Sub
        End If
    
    End Sub
    
    Private Sub Form_Load()
     Dim s As String
        s = ChrW$(1255)
        UniCaption(Me.hwnd) = s
    
        Set cSubClass = New ClsSubclass
    
        If cSubClass.ssc_Subclass(Form1.hwnd, , , Me) Then
           cSubClass.ssc_AddMsg Form1.hwnd, WM_NCPAINT, MSG_BEFORE
        End If    
    End Sub

  22. #22

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    @Elroy: Thank you very much but your code not working too on classical theme.
    Last edited by vietnamvodich; Dec 29th, 2017 at 03:35 AM.

  23. #23
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,728

    Re: Unicode caption for form: not working with classic or non-themed mode

    Here is a solution without even subclassing. It turns the window from ANSI to Unicode via SetWindowLongW and GWL_WNDPROC.

    Code:
    '**************************************
    ' Name: UniCaption - unicode caption for your forms
    ' Description:By a request here, I was fooling around with different ways of changing a form's caption to Unicode. I've seen commercial controls that take over the drawing routine with some heavy subclassing and other similar poor attempts, which have then broken, if not when theme changes, then by when Vista got released.
    I started off by figuring out a way to create a custom Unicode window and then make an existing form a child of it, but this got pretty messy and I wasn't very happy with the complexity. However, I had a bug during this process that I by mistake used a non-Unicode version of DefWindowProc, which prevented the caption to be Unicode. And it didn't take me long to figure out that by temporarily changing a window's window procedure any window caption can be made Unicode.
    So here it is: a very short and clean way to have an Unicode caption in your forms! The code can be pasted directly to your form.
    ' By: Vesa Piittinen (from psc cd)
    '**************************************
    
    Option Explicit
    Private Declare Function GetModuleHandleW Lib "kernel32" (ByVal lpModuleName As Long) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private Declare Function GetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function SetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function SetWindowLongW Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function SetWindowTextW Lib "user32" (ByVal hWnd As Long, ByVal lpString As Long) As Long
    Private Const GWL_WNDPROC = -4
    Private m_Caption As String
    Public Property Get CaptionW() As String
    CaptionW = m_Caption
    End Property
    Public Property Let CaptionW(ByRef NewValue As String)
    Static WndProc As Long, VBWndProc As Long
    m_Caption = NewValue
    ' get window procedures if we don't have them
    If WndProc = 0 Then
    ' the default Unicode window procedure
    WndProc = GetProcAddress(GetModuleHandleW(StrPtr("user32")), "DefWindowProcW")
    ' window procedure of this form
    VBWndProc = GetWindowLongA(hWnd, GWL_WNDPROC)
    End If
    ' ensure we got them
    If WndProc <> 0 Then
    ' replace form's window procedure with the default Unicode one
    SetWindowLongW hWnd, GWL_WNDPROC, WndProc
    ' change form's caption
    SetWindowTextW hWnd, StrPtr(m_Caption)
    ' restore the original window procedure
    SetWindowLongA hWnd, GWL_WNDPROC, VBWndProc
    Else
    ' no Unicode for us
    Caption = m_Caption
    End If
    End Property
    ' usage sample
    Private Sub Form_Load()
    ' some hiragana (you need Japanese fonts installed to see them)
    CaptionW = ChrW$(&H3042) & ChrW$(&H3044) & ChrW$(&H3046) & ChrW$(&H3048) & ChrW$(&H304A) & " ovat japanilaisia hiragana-merkkej�."
    End Sub

  24. #24

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Krool View Post
    Here is a solution without even subclassing. It turns the window from ANSI to Unicode via SetWindowLongW and GWL_WNDPROC.

    Code:
    '**************************************
    ' Name: UniCaption - unicode caption for your forms
    ' Description:By a request here, I was fooling around with different ways of changing a form's caption to Unicode. I've seen commercial controls that take over the drawing routine with some heavy subclassing and other similar poor attempts, which have then broken, if not when theme changes, then by when Vista got released.
    I started off by figuring out a way to create a custom Unicode window and then make an existing form a child of it, but this got pretty messy and I wasn't very happy with the complexity. However, I had a bug during this process that I by mistake used a non-Unicode version of DefWindowProc, which prevented the caption to be Unicode. And it didn't take me long to figure out that by temporarily changing a window's window procedure any window caption can be made Unicode.
    So here it is: a very short and clean way to have an Unicode caption in your forms! The code can be pasted directly to your form.
    ' By: Vesa Piittinen (from psc cd)
    '**************************************
    
    Option Explicit
    Private Declare Function GetModuleHandleW Lib "kernel32" (ByVal lpModuleName As Long) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private Declare Function GetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function SetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function SetWindowLongW Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function SetWindowTextW Lib "user32" (ByVal hWnd As Long, ByVal lpString As Long) As Long
    Private Const GWL_WNDPROC = -4
    Private m_Caption As String
    Public Property Get CaptionW() As String
    CaptionW = m_Caption
    End Property
    Public Property Let CaptionW(ByRef NewValue As String)
    Static WndProc As Long, VBWndProc As Long
    m_Caption = NewValue
    ' get window procedures if we don't have them
    If WndProc = 0 Then
    ' the default Unicode window procedure
    WndProc = GetProcAddress(GetModuleHandleW(StrPtr("user32")), "DefWindowProcW")
    ' window procedure of this form
    VBWndProc = GetWindowLongA(hWnd, GWL_WNDPROC)
    End If
    ' ensure we got them
    If WndProc <> 0 Then
    ' replace form's window procedure with the default Unicode one
    SetWindowLongW hWnd, GWL_WNDPROC, WndProc
    ' change form's caption
    SetWindowTextW hWnd, StrPtr(m_Caption)
    ' restore the original window procedure
    SetWindowLongA hWnd, GWL_WNDPROC, VBWndProc
    Else
    ' no Unicode for us
    Caption = m_Caption
    End If
    End Property
    ' usage sample
    Private Sub Form_Load()
    ' some hiragana (you need Japanese fonts installed to see them)
    CaptionW = ChrW$(&H3042) & ChrW$(&H3044) & ChrW$(&H3046) & ChrW$(&H3048) & ChrW$(&H304A) & " ovat japanilaisia hiragana-merkkej�."
    End Sub
    Hi, I just tried on Windows Server 2008 R2 and not working too :

    Name:  title.png
Views: 689
Size:  1.1 KB

  25. #25

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    I think that the problem is in classical theme, Windows will look at the property of the windows to see if it was created by CreateWindowExA or CreateWindowExW (also must go with RegisterClassA/RegisterClassW) . If it's the Unicode ( W ) version it will look for the BSTR , else look for the ANSI string. By default, VB6 create the Window using CreateWindowExA and RegisterClassA so it's the problem.

  26. #26
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Krool View Post
    Here is a solution without even subclassing. It turns the window from ANSI to Unicode via SetWindowLongW and GWL_WNDPROC.
    That's what the OP started with (and which I've tried to condense somewhat in #2) -
    It still only solves part1 (the placement of a W-caption). The NCPaint problem remains (when unthemed).

    Olaf

  27. #27
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,728

    Re: Unicode caption for form: not working with classic or non-themed mode

    Normally the WM_NCPAINT subclass should do the Job.

    Did you also try both, SetWindowLongW turning (code I just previously posted) and the WM_NCPAINT subclass?

  28. #28
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,728

    Re: Unicode caption for form: not working with classic or non-themed mode

    Also how does your subclasser work? Any ANSI API's involved there what could break something?

  29. #29
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Krool View Post
    Normally the WM_NCPAINT subclass should do the Job.

    Did you also try both, SetWindowLongW turning (code I just previously posted) and the WM_NCPAINT subclass?
    As said, the "SetWindowLongW turning-code" was, what the OP originally started with -
    and it does that "turning" only for a very short moment (followed by a restore of the original ANSI-HandlerProc) -
    so the better alternative to that is, to call DefWindowProcW directly (completely avoiding that swapping).

    An NCPaint-SubClassing-approach (which delegates the Handling of WM_NCPAINT to DefWindowProcW) will have to take into account,
    that the NCPaint-rendering-section inside DefWindowProcW internally has to perform a lookup for the current Caption-String of that Window -
    which will result in an internally called SendMessageW (with WM_GETTEXT) to the hWnd in question.

    And to rule out, that this WM_GETTEXT-request is answered by the ANSI-default-HandlerProc, that message has to be included in the Subclassing as well:
    Below is a solution that shows the Minimum-Efforts needed for Unicode-Caption with SubClassing (please exchange the RC5-SubClasser to the one of your choice):

    Code:
    Option Explicit
     
    Private Const WM_SETTEXT& = &HC, WM_GETTEXT = &HD, WM_NCPAINT = &H85
    Private Declare Function DefWindowProcW& Lib "user32" (ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
    
    Private WithEvents SC As vbRichClient5.cSubClass
     
    Private Sub Form_Load()
      Set SC = New_c.SubClass: SC.Hook hWnd
      CaptionW = ChrW$(1088) & ChrW$(1089) & ChrW$(1090) & ChrW$(1091)
    End Sub
    
    Public Property Get CaptionW() As String
      CaptionW = Space$(2048)
      CaptionW = Left$(CaptionW, DefWindowProcW(hWnd, WM_GETTEXT, Len(CaptionW), StrPtr(CaptionW)))
    End Property
    Public Property Let CaptionW(ByVal RHS As String)
      DefWindowProcW hWnd, WM_SETTEXT, Len(RHS), StrPtr(RHS)
    End Property
    
    Private Sub SC_WindowProc(Result As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long)
      Select Case Msg
        Case WM_NCPAINT, WM_GETTEXT '<- include WM_GETTEXT as being handled by the W-version as well
          Result = DefWindowProcW(hWnd, Msg, wParam, lParam)
        Case Else
          Result = SC.CallWindowProc(Msg, wParam, lParam)
      End Select
    End Sub
    Olaf

  30. #30

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Schmidt View Post
    As said, the "SetWindowLongW turning-code" was, what the OP originally started with -
    and it does that "turning" only for a very short moment (followed by a restore of the original ANSI-HandlerProc) -
    so the better alternative to that is, to call DefWindowProcW directly (completely avoiding that swapping).

    An NCPaint-SubClassing-approach (which delegates the Handling of WM_NCPAINT to DefWindowProcW) will have to take into account,
    that the NCPaint-rendering-section inside DefWindowProcW internally has to perform a lookup for the current Caption-String of that Window -
    which will result in an internally called SendMessageW (with WM_GETTEXT) to the hWnd in question.

    And to rule out, that this WM_GETTEXT-request is answered by the ANSI-default-HandlerProc, that message has to be included in the Subclassing as well:
    Below is a solution that shows the Minimum-Efforts needed for Unicode-Caption with SubClassing (please exchange the RC5-SubClasser to the one of your choice):

    Code:
    Option Explicit
     
    Private Const WM_SETTEXT& = &HC, WM_GETTEXT = &HD, WM_NCPAINT = &H85
    Private Declare Function DefWindowProcW& Lib "user32" (ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
    
    Private WithEvents SC As vbRichClient5.cSubClass
     
    Private Sub Form_Load()
      Set SC = New_c.SubClass: SC.Hook hWnd
      CaptionW = ChrW$(1088) & ChrW$(1089) & ChrW$(1090) & ChrW$(1091)
    End Sub
    
    Public Property Get CaptionW() As String
      CaptionW = Space$(2048)
      CaptionW = Left$(CaptionW, DefWindowProcW(hWnd, WM_GETTEXT, Len(CaptionW), StrPtr(CaptionW)))
    End Property
    Public Property Let CaptionW(ByVal RHS As String)
      DefWindowProcW hWnd, WM_SETTEXT, Len(RHS), StrPtr(RHS)
    End Property
    
    Private Sub SC_WindowProc(Result As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long)
      Select Case Msg
        Case WM_NCPAINT, WM_GETTEXT '<- include WM_GETTEXT as being handled by the W-version as well
          Result = DefWindowProcW(hWnd, Msg, wParam, lParam)
        Case Else
          Result = SC.CallWindowProc(Msg, wParam, lParam)
      End Select
    End Sub
    Olaf
    AMAZING! THIS CODE ABSOLUTELY WORKING ! THANK YOU VERY VERY VERY MUCH SCHMIDT!!

    I also tested and It's can also work without WM_NCPAINT
    Code:
     Case WM_GETTEXT '<- no need WM_NCPAINT here
          Result = DefWindowProcW(hWnd, Msg, wParam, lParam)
    Thank everyone for your support , really amazing forum, I wish everybody here all super long life and living forever !! Happy new year in advance.

  31. #31
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,229

    Re: Unicode caption for form: not working with classic or non-themed mode

    so full the solution was not only calling DefWindowProcW to set the text, but also subclassing WM_GETTEXT.

    Thanks Krool, Schmidt. This should be added to the Unicode FAQ.


    @Schmidt. If you're calling a custom constructor / class factory, you could include parameters.

    Code:
    Set SC = New_c.SubClass(hWnd)
    Last edited by DEXWERX; Dec 29th, 2017 at 09:45 AM.

  32. #32
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Unicode caption for form: not working with classic or non-themed mode

    I definitely believe that it works (although I can't test on these older OSs), but it's puzzling to me as to why.

    We certainly know that nothing has changed about VB6 through the years (other than the service packs). So, why does circumventing the internal VB6 subclassing for a WM_GETTEXT fix the problem on some OSs and isn't needed on others? This would suggest that VB6 code is behaving differently (i.e., converting to ANSI) on Windows XP & Vista, whereas it's not on Win7 and beyond.

    Happy New Year,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  33. #33
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,229

    Re: Unicode caption for form: not working with classic or non-themed mode

    Runtimes are updated and patched for each OS, starting with Vista. That means msvcrt40 and msvbvm60 are hopefully not the original runtimes, but ones that came with the O/S.

    edit: this is why we keep recommending on here not to redist the runtime. Later Windows versions do seem smart enough to block installers from replacing the updated runtimes with older versions.
    Last edited by DEXWERX; Dec 29th, 2017 at 10:04 AM.

  34. #34
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Unicode caption for form: not working with classic or non-themed mode

    Hi Dex,

    Yeah, I was thinking (wondering about) that too. It would seem that that's almost got to be the answer.

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  35. #35
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Unicode caption for form: not working with classic or non-themed mode

    Or just maybe, this is a pleasant result of Windows redirecting some API functions, much like it does for other APIs, like DPI-related ones?
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  36. #36
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,728

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by vietnamvodich View Post
    I also tested and It's can also work without WM_NCPAINT
    Code:
     Case WM_GETTEXT '<- no need WM_NCPAINT here
          Result = DefWindowProcW(hWnd, Msg, wParam, lParam)
    I would keep WM_NCPAINT to be on secure side. Even it is unecessary it does not harm.

    @ Schmidt,
    I just found the snippet in quick and didn't realize that the SetWindowLongW "turning" is just temporary to set the W-String in place. Of course the DefWindowProcW set text is the way to go, I just miss-interpreted the snippet just found.

    So yes, in order to support full unicode, even on classic theme, a "small" subclass is needed.

  37. #37
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Unicode caption for form: not working with classic or non-themed mode

    Looks good.

    Here is a version that has no extra dependency, though that means the subclassing can be IDE-fragile of course (be wary when debugging):

    Name:  sshot1.png
Views: 675
Size:  1.2 KB


    Name:  sshot2.png
Views: 646
Size:  1.1 KB


    Nothing original here. It just repackages the ideas posted above.
    Attached Files Attached Files

  38. #38
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by Krool View Post
    I would keep WM_NCPAINT to be on secure side. Even it is unecessary it does not harm.
    Yep, I was going to suggest keeping that in the DefWindowProcW-branch as well
    (why leave it to chance, what the next "CallWindowProc" in the chain might do or not do).

    @Dex
    Code:
      Set SC = New_c.SubClass(hWnd)
    Yep, duly noted - there is also several other (still "naked") cConstructor-HandOuts, which could profit from an extension in that regard
    (as e.g. New_c.Stream(SomeInitialByteArray) or New_c.SVG(SomeUTF8SvgBytes) + a few others...).

    Will wait with these for RC6 - not wanting to risk breaking BinComp or ClassIDs on RC5 at this point.

    Olaf

  39. #39

    Thread Starter
    Lively Member
    Join Date
    Apr 2015
    Posts
    72

    Re: Unicode caption for form: not working with classic or non-themed mode

    Quote Originally Posted by dilettante View Post
    Looks good.

    Here is a version that has no extra dependency, though that means the subclassing can be IDE-fragile of course (be wary when debugging):

    Name:  sshot1.png
Views: 675
Size:  1.2 KB


    Name:  sshot2.png
Views: 646
Size:  1.1 KB


    Nothing original here. It just repackages the ideas posted above.
    Hi dilettante ! Thank you a lot for your contribution. This subclass work great but I realized that it crash when use the End command to exit the program. Is there any better version?

  40. #40
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Unicode caption for form: not working with classic or non-themed mode

    Programs should never have an End statement.

    In any case the only easy IDE-safe way to handle subclassing is to use a separately compiled DLL that can unsubclass when the class it houses terminates. You could rewrite the subclassing logic as a class in your own DLL or use one provided by somebody else.

Page 1 of 2 12 LastLast

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