Results 2,641 to 2,680 of 4199

Thread: CommonControls (Replacement of the MS common controls)

Threaded View

  1. #11

    Thread Starter
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,728

    Re: CommonControls (Replacement of the MS common controls)

    Update released.
    Sorry for the ongoing updates with CommonDialog.cls
    Hopefully this is now final.

    Quote Originally Posted by Simos View Post
    Yes. This is the perfect logic.
    Almost. Now only the PropPrinterName is used to select a non-default printer on initialization.
    Also the DEVNAMES structure is now always filled according to the DeviceName. (which can be GetPrinterDefault() or PropPrinterName)
    DEVNAMES is important if the printer name is > 32 chars. (if less 32 then DMDeviceName will be read)
    Also PropPrinterDriver and PropPrinterPort are not needed actually, so there are ignored on input.
    On output (dialog function returns) of course the DEVNAMES will be read and all PropPrinterName/PropPrinterDriver/PropPrinterPort will be set.
    I played around very extensively now and this logic must be the "correct" one.

    In code this means following: (changes marked as red)
    Code:
    Dim hPrinter As Long, DeviceName As String, DMODE_B() As Byte, dwBytes As Long
    If PropPrinterDefaultInit = False And Not PropPrinterName = vbNullString Then
        DeviceName = PropPrinterName
        dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
        If dwBytes = 0 Then
            ' Fallback to default printer as user-defined printer name is invalid.
            DeviceName = GetPrinterDefault()
            dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
        End If
    Else
        DeviceName = GetPrinterDefault()
        dwBytes = PrepareDevModeBuffer(hPrinter, DeviceName, DMODE_B())
    End If
    If dwBytes > 0 Then
        [...]
    Code:
        [...]
        If Not DeviceName = vbNullString Then
            ' wDeviceOffset will only be used on input when DMDeviceName got truncated due to the 32 characters limit.
            ' wDriverOffset and wOutputOffset are ignored on input.
            DNAMES.wDriverOffset = 4
            DNAMES.wDeviceOffset = DNAMES.wDriverOffset + 1
            DNAMES.wOutputOffset = DNAMES.wDeviceOffset + Len(DeviceName) + 1
            DNAMES.wDefault = 0
            Buffer = Left$(vbNullChar & DeviceName & vbNullChar & vbNullChar, CCHDEVNAMESEXTRA)
            CopyMemory DNAMES.wExtra(0), ByVal StrPtr(Buffer), LenB(Buffer)
            PDLG.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, LenB(DNAMES))
            lpDevNames = GlobalLock(PDLG.hDevNames)
            CopyMemory ByVal lpDevNames, DNAMES, LenB(DNAMES)
            GlobalUnlock PDLG.hDevNames
        End If
    End If
    Quote Originally Posted by Simos View Post
    Did you test the Generic / Text Only ?
    No. Why?

    EDIT:
    Another gotcha fixed. (potential memory issue)
    On return, when reading hDevNames, the size is flexible. So instead using LenB(DNAMES) now use GlobalSize().
    I defined CCHDEVNAMESEXTRA as 200 to ensure big enough buffer. However, it may be smaller when not necessary.
    And therefore using LenB(DNAMES) could CopyMemory too much, out of scope of the allocated memory block.
    So GlobalSize() should be the safe way.
    Code:
    If PDLG.hDevNames <> 0 Then
        ' DEVNAMES is a variable length memory block.
        Dim dwMemSize As Long
        dwMemSize = GlobalSize(PDLG.hDevNames)
        If dwMemSize > LenB(DNAMES) Then dwMemSize = LenB(DNAMES)
        Erase DNAMES.wExtra()
        lpDevNames = GlobalLock(PDLG.hDevNames)
        CopyMemory DNAMES, ByVal lpDevNames, dwMemSize
        GlobalUnlock PDLG.hDevNames
        GlobalFree PDLG.hDevNames
        [...]
    Last edited by Krool; Mar 4th, 2020 at 04:39 PM.

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