Page 1 of 4 1234 LastLast
Results 1 to 40 of 121

Thread: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Trick)

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Post Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Trick)

    I am not able to display form in the new thread. I included f as Object as new field in ThreadData structure and I am trying to display the form sent from testGraphicsdll.vbp by extracting the form
    in the thread procedure in Graphicsdll.vbp when I select Saturation in the combobox.But nothing is displayed. (The following code is from member The Trick, with some modifications by me)
    -------------------------------------------------------------------------------------------------------------------------
    The following structure is used in both Graphicsdll and testGraphicsdll projects both of which are in
    GraphicsNativedll folder.
    Private Type ThreadData
    pix() As Byte
    Value As Single
    percent As Single
    f As Object ' new field added by me
    End Type

    Private Sub RunProcedure(Name As String, ByVal value As Single)
    Dim lpProc As Long
    ' Åñëè â î÷åðåäè óæå åñòü âûçîâ âûõîäèì
    If quene Then Exit Sub
    ' Åñëè ïîòîê àêòèâåí, òî ñòàâèì â î÷åðåäü òåêóùèé âûçîâ è âûõîäèì
    If hThread Then quene = True: Exit Sub
    ' Ïîëó÷àåì àäðåñ ôóíêöèè
    lpProc = GetProcAddress(hLib, Name)
    If lpProc = 0 Then MsgBox "Íåâîçìîæíî íàéòè ôóíêöèþ": Exit Sub
    ' Óñòàíàâëèâàåì çíà÷åíèå ýôôåêòà
    td.value = value
    Set td.f = Main ' added new form here
    ' Ïîëó÷àåì ïèêñåëè ðèñóíêà
    GetDIBits picCanvas.hdc, pic.Handle, 0, bi.bmiHeader.biHeight, td.pix(0, 0), bi, 0
    ' Ñîçäàåì ïîòîê
    hThread = CreateThread(ByVal 0&, 0, lpProc, td, 0, 0)
    ' Âêëþ÷àåì òàéìåð ïðîãðåññáàðà
    'tmrUpdate.Enabled = True
    End Sub


    Public Function Saturation(dat As ThreadData) As Long
    Dim x As Long
    Dim y As Long
    Dim w As Long
    Dim h As Long
    Dim tmp As Long
    Dim r As Long
    Dim g As Long
    Dim b As Long
    Dim br As Long
    Dim Value As Single
    Dim f As Object
    On Error GoTo ERRORLABEL
    RemoveLastDllError
    MsgBox "in sat" ' iam getting this messagebox
    Set f = dat.f 'added by me
    f.Show vbModal ' form not displayed
    MsgBox "in sat1" ' i am not getting this messagebox
    Value = dat.Value
    If Value > 1 Then Value = 1
    If Value < 0 Then Value = 0

    w = UBound(dat.pix, 1) \ 4
    h = UBound(dat.pix, 2)

    For y = 0 To h
    For x = 0 To w
    b = dat.pix(x * 4, y)
    g = dat.pix(x * 4 + 1, y)
    r = dat.pix(x * 4 + 2, y)
    br = 0.3 * r + 0.59 * g + 0.11 * b
    r = r * Value + br * (1 - Value)
    g = g * Value + br * (1 - Value)
    b = b * Value + br * (1 - Value)
    dat.pix(x * 4, y) = b
    dat.pix(x * 4 + 1, y) = g
    dat.pix(x * 4 + 2, y) = r
    Next
    dat.percent = y / h
    Next

    dat.percent = 1
    Saturation = 1

    ERRORLABEL:

    End Function
    ------------------------------------------------------------

    Thanks
    Attached Files Attached Files

  2. #2

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Thankyou for the prompt response.
    I have gone thru your links.
    But I want to display a form in the .exe in the new thread created in the .dll .
    I am able to do the same using http://www.vbforums.com/showthread.p...n-Standart-EXE in the same exe in new thread but it fails if I try to do the same using in new thread in a dll.
    As you said if I try to add a form in a dll project it becomes local to dll which is not accessible through .exe.
    I should be able to send form from exe project to dll project and the dll project should be able to display it in new thread.
    Are there any alternate methods as using varptr,objptr and copymemory.Please help.

  4. #4
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Sorry my English. Look. No matter how you do it. Main condition is initialize project in new thread. For example - if you want to work with forms declared in the EXE project you just create new thread in EXE and call function (exported from DLL) in this thread. There you can pass any object, only you should make a marshalling if your form is shared between threads.
    Look this simple example. You create a native dll which exported function ShowForm:
    vb Code:
    1. Option Explicit
    2.  
    3. Public Function ShowForm(frmForm As Form, Caption As String) As Long
    4.     On Error GoTo ERRORLABEL
    5.    
    6.     ' just for example
    7.     frmForm.Caption = Caption
    8.     frmForm.Show vbModal
    9.    
    10. ERRORLABEL:
    11.  
    12. End Function
    Ok. Now in order to showing the passed form from any project (EXE, DLL) you must initialize project with this form in the new thread. If it's a DLL project you just passed as is, because before calling the desired function DllMain being called, which initialize project. If it's a Standart-EXE project then you must manually initialize this project. To do this you can use my module, or any other approach (i have not seen).
    For example if you would use my module:
    This is module which contained thread procedure and it call your exported function from dll. Also it pass your form into the DLL from EXE:
    vb Code:
    1. Option Explicit
    2.  
    3. Private Declare Function ShowForm Lib "ShowFormDll.dll" (frmForm As Form, ByVal Caption As Long) As Long
    4.  
    5. Public Function ThreadProc(ByVal unUsed As Long) As Long
    6.     On Error GoTo ERROR_HANDLER
    7.    
    8.     ShowForm New frmMain, VarPtr("New thread form " & App.ThreadID)
    9.    
    10.     Exit Function
    11.    
    12. ERROR_HANDLER:
    13.    
    14.     MsgBox Err.Description
    15.    
    16. End Function
    As you see, i pass string as VarPtr because VB6 convert all passed string (Declared API) to ANSI and vice versa, but ShowForm expect BSTR variable in the second parameter. If you declare this function in TLB (properly, as BSTR) then you could call it without VarPtr. This function being called in new thread. Also, in order to not use a marshalling i send new form - it is important. This form just not shared between threads. If i call just frmMain then error and crash occurs.
    Ok. And in order to call this function you should use it code:
    vb Code:
    1. Private Sub cmdShowForm_Click()
    2.     Dim hThread As Long
    3.    
    4.     hThread = vbCreateThread(0, 0, AddressOf ThreadProc, 0, 0, 0)
    5.     CloseHandle hThread
    6.    
    7. End Sub
    Importand: you should (must) always close all unused handles.
    Attached Files Attached Files

  5. #5
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    @jsvenu
    Just posted an example which shows an alternative way of:
    "creating AX-Dll-ClassInstances on their own threaded Apartments"
    into the Codebank: http://www.vbforums.com/showthread.p...-dll-HelperLib

    Maybe that's a bit easier to understand and handle (because it leaves a bit less room for mistakes).



    Olaf

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    thankyou for the reply.
    But in the code

    ShowForm New frmMain, VarPtr("New thread form " & App.ThreadID

    in ThreadProc frmMain refers to form in the .exe.

    But I want to show a unused form existing in the workspace of current standard exe project through a thread created in the dll project.
    I want a .dll project(say library) to which I can send form as parameter and it should display the form in a thread.
    I am able to do the above in the dll directly in the main thread of dll but failed to display in the create in secondary thread.
    Please clarify.

  7. #7
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Quote Originally Posted by jsvenu View Post
    in ThreadProc frmMain refers to form in the .exe.
    I don't understand you. Look. Firstly it work only compiled project (while i don't add IDE-support in my module), i mean creating thread in EXE. But as i said in order to pass form as parameter in new thread you must initialize this form (it mean you must initialize project with this form) in new thread. How you doing it - no matter, without initialization form don't showing anyway. As you see i create new thread in exe and it initializing project for new thread, only after it i pass form in DLL.

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    I want to send a form in .exe from the main thread to .dll which takes form as input parameter and inturn the .dll creates new thread in which it displays the form received from .exe.
    I don't want to create new thread in .exe and I want to send it to .dll from the existing main thread itself.I want the form to be displayed in the new thread created in dll.
    I will be running outside IDE in compiled mode only.Please help.

  9. #9
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    I gave you an example exactly. There i send the form from exe to dll, and show it into dll.
    Quote Originally Posted by jsvenu View Post
    I want to send a form in .exe
    contained in exe?
    Quote Originally Posted by jsvenu View Post
    from the main thread to .dll which takes form as input parameter and inturn the .dll creates new thread in which it displays the form received from .exe.
    Same form or lot of forms? But as i said if your form is shared then you should use a marshalling. Also you must initialize project in which contained a desired form.
    Quote Originally Posted by jsvenu View Post
    I don't want to create new thread in .exe and I want to send it to .dll from the existing main thread itself.
    You cannot just send reference of form between threads. Before passing you must initialize project which contained desired form, also you must care about synchronization. No matter as you create the thread - either in EXE or in DLL if you further anyway call exported function. In my GraphicsDll project i call all functions directly in new thread, ie each function was a ThreadProc. But i just could create a thread in exe and call these functions being used Decalred-statement.
    Quote Originally Posted by jsvenu View Post
    I want the form to be displayed in the new thread created in dll.
    I gave you an example above.

  10. #10

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Thank you very much for the explanation.
    I use vc++ win32 and MFC frequently in which anything is possible using threading.
    I am familiar with activex dll, activex exe and standalone exe in VB6.
    But the examples given by you seems to use native dlls in vb6.
    Can you suggest basic steps to create native dlls in vb6 and creating type libraries in vb6 since they are not directly available to vb6 IDE.

  11. #11
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Quote Originally Posted by jsvenu View Post
    But the examples given by you seems to use native dlls in vb6.
    If you ask me, then i reply. This example used DLL only because that article explain how create DLL, and create thread there.
    Quote Originally Posted by jsvenu View Post
    Can you suggest basic steps to create native dlls in vb6 and creating type libraries in vb6 since they are not directly available to vb6 IDE.
    This article entirely explain how i was create Native-dll. This article also explain how i create dll for global-hook. Main idea is used any linker options, and two BAS-modules: first for a shared data, second for no shared data. You choose what is module you desired. Also you can look this driver-project, which also is DLL, only for kernel-mode. Same idea - i just use linker options inside the .vbp-file.

    If you want to create TypeLibraries then you can use a MIDL compiler which is allowed in VS. I always use it.

    Once again. I wrote 4 articles which explain how work with threading.
    1. Creating a object (declared by ActiveX Dll) into new thread and work with that object. This project respectively require ActiveX Dll which contained the desired object. Link.
    2. Creating a native DLL (i entirely explain how create native-dll in vb6 step-by-step) and create thread in some exported function from that DLL. It work with IDE because i don't use additional code; i use directly call. This project respectively require Native DLL which contained the desired functions. Link
    3. Creating a native DLL which being used in any other process. This article show that DLL being created in VB6 are worked in any process. This project respectively require Native DLL because global hook must be in DLL. Link.
    4. Creating thread in Standart-EXE project, without external dependencies, ie i explain how create the analog of CreateThread function which will be working correctly in VB6. This project don't use external dependencies - after compiling it is the independent module. Link.

    Almost all examples use type libraries which no needed after compiling. Perhaps i bad explain this because my English is bad, therefore you can ask me.

  12. #12

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Friend Trick,

    Thank you for the reply.

    I am sending you a link

    https://www.planet-source-code.com/v...26900&lngWId=1

    which contains generic multithreading library(MThreadVB) as well as demo project(MThreadDemo)demonstrating how to use the above library.

    It works well for any background operations like finding primes.
    But even though it can display forms and perform file IO in new thread it blocks the main thread.

    If you can go through it and using your vbCreateThread trick to make it execute any function
    executing backgroung operation or display a form or doing file IO to execute in a new thread
    by calling CallByName VB 6 function without blocking the main thread
    the library will be functionally complete.

    Please help.

  13. #13

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Friend Trick,

    Thank you for the reply.

    I am sending you a link

    https://www.planet-source-code.com/v...26900&lngWId=1

    which contains generic multithreading library(MThreadVB) as well as demo project(MThreadDemo)demonstrating how to use the above library.

    It works well for any background operations like finding primes.
    But even though it can display forms and perform file IO in new thread it blocks the main thread.

    If you can go through it and using your vbCreateThread trick to make it execute any function
    executing backgroung operation or display a form or doing file IO to execute in a new thread
    by calling CallByName VB 6 function without blocking the main thread
    the library will be functionally complete.

    Please help.

  14. #14

  15. #15

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,
    I am sending the generic multithreader as zip file in attachment.
    Please go thru and help for displaying forms modally and file IO in new thread using callbyvalue without blocking main thread.It works fine for background operations like finding primes shown in eample in attachment.
    Attached Files Attached Files

  16. #16
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Quote Originally Posted by jsvenu View Post
    But even though it can display forms and perform file IO in new thread it blocks the main thread.
    In this example form show in main thread. You can add line Me.Caption = App.ThreadId to verify this. As i said you don't work with object if it not initialized. In this example threads are unstable, it work only with very restricted commands. If you look this code then you seen that it use marshalling for a form. It mean that all calls translate in thread which contain original object ie in main thread. This code very restrict because it not work with any object in new thread (for example try add to FindPrimes any private class and try work with it).
    Look:
    vb Code:
    1. Set Obj = CoGetInterfaceAndReleaseStream(NewThreadInfo.cStream, IID_IUnknown)
    2. NewThreadInfo.ThreadClass.SetContextObject Obj
    3. . . .
    4. ' Here properly instead NewThreadInfo.ClientObject you must pass Obj, because
    5. ' you shouldn't send link on private (single-threaded) object between threads without marshalling.
    6. ' it would work perfect without crashes and restriction,
    7. ' but it just translate all query in the main thread and performs there, that no advantages.
    8. CallByName NewThreadInfo.ClientObject, FuncName, VbMethod, NewThreadInfo.FuncParam
    Honestly, i think it is wrong. Even in code author write:
    vb Code:
    1. 'This is the multithreaded procedure... We cannot
    2. 'directly load a form here, since doing so will cause
    3. 'VB to crash... We must call the Main Thread and make
    4. 'it perform the Form load operation...
    5. 'The ObjectInThreadContext property returns a reference
    6. 'to the original Form (Form1) running on the original
    7. 'Thread... We call the ShowFormNow() Sub to show the form
    8. 'But this Sub is called in context to the original Thread
    9. FormThread.ObjectInThreadContext.ShowFormNow (CLng(ModalFlag))
    Here author pass properly references (marshalled), and it show form in new thread. Here you cannot performs VDialog.Show, because project not initialized in new thread.
    REMEMBER: you cannot work with privates objects if project not initialized, never.
    This code is similar to my code, when i wrote about multithreading (part 1) and work with object in new thread. There i also used marshalling, but it supported synchronously and asynchronously calls.
    I so far don't understand what you want. My module support any operations in new thread. Send me code which contained your desired code, only use stub-function for create thread. I remake this code that it will be work in different thread.

    btw in attach multithreading code which open form in another thread and run there search in files.
    Attached Files Attached Files

  17. #17

  18. #18

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,
    First let me thank you for the reply.
    As you said,
    only use stub-function for create thread means I have to include modThreading.bas module in every project wherever I use CreateThread api.
    So I request you to include this vbCreateThread containing module in dll which exports this global vbCreateThread function.
    Then simply I can use the vbreateThread function thru declare statement instead of including modThreading module in every
    project.This is the library or dll I was asking you.
    By the way you told to see in codeBank.Where can I find code bank in VBforums.

  19. #19
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Quote Originally Posted by jsvenu View Post
    So I request you to include this vbCreateThread containing module in dll which exports this global vbCreateThread function.
    Then simply I can use the vbreateThread function thru declare statement instead of including modThreading module in every
    project.This is the library or dll I was asking you.
    In attach. Declaration:
    vb Code:
    1. Private Declare Function vbCreateThread Lib "TrickMultithreading" ( _
    2.                          ByVal lpThreadAttributes As Long, _
    3.                          ByVal dwStackSize As Long, _
    4.                          ByVal lpStartAddress As Long, _
    5.                          ByVal lpParameter As Long, _
    6.                          ByVal dwCreationFlags As Long, _
    7.                          ByRef lpThreadId As Long) As Long
    Quote Originally Posted by jsvenu View Post
    By the way you told to see in codeBank. Where can I find code bank in VBforums.
    Here, it very useful resource.
    Attached Files Attached Files

  20. #20

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,
    Thankyou for the reply.
    I tried to copy code related to vbCreateThread from modMultithreading.bas module to modMain.bas andtried to make showformdll.dll using showformdll project sent by you.But when I check showform.dll using dependency viewer or dumpbin -exports I am seeing only showform function exported and no vbCreateThread exported.Am I missing something. Please clarify?

  21. #21

  22. #22

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Thank you trick.Got it.

  23. #23

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,
    When I run the application using vbCreateThread in a module it works fine but when I use vbCreateThread exported by dll
    I get error and the application terminates.This happens even if I put ThreadProc as empty function without any code to display a new form.I have kept two buttons with show form in thread using module and show form in thread using dll in the GUI.If I click on show form in thread using module the app works fine after which if I click show form in thread[/B] using dll I get trickthread.dll not found.If I click show form in thread using dll[/B] first itself it crashes.
    Generally dll loads in exe's address space.Am I missing something.Please clarify.
    I am sending dll and app using the dll as attachment.
    Attached Files Attached Files

  24. #24

  25. #25

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,
    Here is the attachment
    Attached Files Attached Files

  26. #26
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Look. It work only either through a DLL or through a module. For example, you cannot create a thread first using DLL and after module, because crash occur. Same if you create first in module you cannot create after through DLL. Generally you cannot combine the methods. You can remake module to it support both methods, but i will not do it because this module need for work in StandartEXE. In order to remake module you must move the writing to VBHeader.lpSubMain into a thread directly. Just if you do not it then both functions will write to original header. And the last writing set a procedure that used its TLS-index. After if you create thread used different method then TlsGetValue read incorrect value because index doesn't match.
    BTW i update module in that thread.
    Attached Files Attached Files

  27. #27

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Thankyou very much trick.

  28. #28

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,

    I tried to display Form1 in project Test1 which uses vbCreateThread after marshalling the form1 by calling function abc defined in the same form which tries to display itself using Me.Show.

    But the application is crashing even after marshalling.Can you go thru and help me where I am doing wrong?
    I am sending Test1 code as attachment.
    Attached Files Attached Files

  29. #29
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    FYI, before using multithreading you should well know it. Your project contains many errors.
    Firstly your declarations of the API functions is incorrect. Where had you found these declaration? Always use MSDN for verifying, also i already published the example of the marshaling usage in the first article about multithreading. There are the proper API declarations:
    Code:
    Public Declare Function CoMarshalInterThreadInterfaceInStream Lib "ole32.dll" (riid As VBGUID, ByVal pUnk As IUnknown, ppStm As Long) As Long
    Public Declare Function CoGetInterfaceAndReleaseStream Lib "ole32.dll" (ByVal pStm As Long, riid As VBGUID, ppv As Any) As Long
    Remember, which interface you marshaled the one you should use in the different thread. In your example you used IUnknown interface for marshalling, but in the different thread you used Form and Form1 interfaces. I don't know exactly if you can use the marshaling with the private interfaces, rather can't. Anyway you can use IDispatch for this purpose.
    Code:
    Option Explicit
    Public f As Form1
    Public Type threadst
        f       As Object
        fcap   As String
        'cStream As Long
    End Type
    Public cStream As Long
    Public Type VBGUID
        data1           As Long
        data2           As Integer
        data3           As Integer
        data4(0 To 7)   As Byte
    End Type
    Public IID_IDispatch As VBGUID
    Public Declare Function CoMarshalInterThreadInterfaceInStream Lib "ole32.dll" (riid As VBGUID, ByVal pUnk As IUnknown, ppStm As Long) As Long
    Public Declare Function CoGetInterfaceAndReleaseStream Lib "ole32.dll" (ByVal pStm As Long, riid As VBGUID, ppv As Any) As Long
    Public Function NewThreadProc(value As threadst) As Long
    Dim iid As VBGUID
    Dim obj As Object
    Dim ret As Long
    Dim frm As Form1
    
    ret = CoGetInterfaceAndReleaseStream(cStream, IID_IDispatch, obj)
    
    If ret Then
        Err.Raise ret
    End If
    
    MsgBox App.ThreadID ' Be sure it is different thread
    
    Call obj.abc
    
    End Function
    Code:
    Option Explicit
    
    Dim xf As threadst ' threadst defined in modNewThreadProc
    Private Sub cmdNewWnd_Click()
        Dim hThread As Long
        Dim capt    As String
        Dim lpCapt  As Long
        Dim res     As Long
        
        'Initialize the IUnknown OLE interface ID structure
        With IID_IDispatch
                .data1 = &H20400
                .data4(0) = &HC0
                .data4(7) = &H46
        End With
    
        Me.Caption = App.ThreadID
        
        Set xf.f = Form1
      
        res = CoMarshalInterThreadInterfaceInStream(IID_IDispatch, xf.f, cStream)
    
        If res Then
            Err.Raise res
        End If
        
        hThread = vbCreateThread(0, 0, AddressOf NewThreadProc, VarPtr(xf), 0, 0) 'NewThreadProc
        
        CloseHandle hThread
        
    End Sub

  30. #30

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,

    Thank you very much for the prompt reply.
    I am attaching the working code after using IDispatch interface.
    I have two doubts in this running code.

    1. Why we should use IDispatch rather than IUnknown .Please clarify?

    2. I am getting different threadid each time I click "window in new thread button" which is correct but I am getting alaways same thread id in the label1 of form1 display.Please clarify?( I am able to move each of main form and each form1 independently when I drag them using left mouse button pressed on caption bar which makes clear that each form is running in different thread)
    Attached Files Attached Files

  31. #31

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,

    If I put modal display of form1 as follows in abc() method of form1

    Public Sub abc()
    Me.Show 1 'form not displayed from thread
    End Sub


    I am getting main thread blocked.
    Is there any way to make the main thread not to block by displaying form1 as Modal as above using vbCreateThread.Please Clarify.

  32. #32
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Quote Originally Posted by jsvenu View Post
    1. Why we should use IDispatch rather than IUnknown .Please clarify?
    You can use IUnknown, but you should call only IUnknown methods. It doesn't make sense because it doesn't have any functional. You can use any public interface, but you can use a manual marshaller. In this case you have to implement all inter-thread communication manually. I wrote the article (first part of the multithreading series) when i marshal user-interface. Generally you should use that interface you specify in the first and second parameters of CoMarshalInterThreadInterfaceInStream function. Just remember it.
    Quote Originally Posted by jsvenu View Post
    2. I am getting different threadid each time I click "window in new thread button" which is correct but I am getting alaways same thread id in the label1 of form1 display.Please clarify?( I am able to move each of main form and each form1 independently when I drag them using left mouse button pressed on caption bar which makes clear that each form is running in different thread)
    Because you use marshalling. Look, you create the form object in the main thread, therefore this form lives in the main thread. When you do the marshaling you just ensure the inter-thread communication without conflict. For example, if you load the main thread using a long cycle and you will try to call a method of the marshaled-object from a different thread, the not-loaded thread will wait until main thread release (or call DoEvents or something else). You can create form in the new thread and marshal it to the main thread.

  33. #33

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,

    Thank you for the clarification.
    You are able to create real thread in vb using your own vbcreatethread.
    I have read your many articles in vb using win32 API.
    Now I understand you have done many things in vb using code to implement assembly
    language using apis like copymemory,createthread etc.
    But the only difference I noticed is just like VC++ (unmanaged code ie.,win32,MFC,ATL)
    in VB6 we cannot do pure multithreading using GUI elements like forms.
    For example in VC++ MFC we can create a class say sdf derived from CDialog and
    create an object in one main thread say
    xyzdlg g_xyzdlg;
    and
    call g_xyzdlg.DoModal()
    in another thread say newthread without blocking main thread.
    Here g_xyzdlg owner will be newthread even though it is created in main thread.
    ie. the message loop of g_xuzdlg is in newthread but not in main
    thread.I am attaching a simple dialog based MFC project as attachment using vc++ 6.0.
    I think this is not possible in VB6 with or without marshalling .
    Is there any way to change form behaviour like this using any assembly language and win32
    or Free threading using FTM(Free Threaded Marshaller) or so or API or hooks or subclassing using pure vb6.
    I shall be grateful to you if you can provide a solution.
    Attached Files Attached Files

  34. #34
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Quote Originally Posted by jsvenu View Post
    in VB6 we cannot do pure multithreading using GUI elements like forms.
    That's also not possible in C/C++ ...
    (hWND - and hWnd-derived cross-thread hDC-Painting per GDI is not threadsafe,
    it should only be done from within the thread which runs the Message-Loop)

    Quote Originally Posted by jsvenu View Post
    create an object in one main thread say
    xyzdlg g_xyzdlg;
    and
    call g_xyzdlg.DoModal()
    in another thread say newthread without blocking main thread.
    Here g_xyzdlg owner will be newthread even though it is created in main thread.
    ie. the message loop of g_xuzdlg is in newthread but not in main
    thread.
    When newthread is the owner of that modally looping form - where's
    the point in creating the (Wnd-)Class elsewhere?

    Quote Originally Posted by jsvenu View Post
    I think this is not possible in VB6 with or without marshalling.
    It is entirely possible in VB, to create and show a TopLevel-hWnd on
    its own thread (with or without marshalling) - and then paint to it ->
    from within that thread - and only from within that thread!

    There's no exception for C/C++ - and neither for .NET.

    Quote Originally Posted by jsvenu View Post
    Is there any way to change form behaviour like this using any assembly language and win32
    or Free threading using FTM(Free Threaded Marshaller) or so or API or hooks or subclassing using pure vb6.
    I shall be grateful to you if you can provide a solution.
    I cannot see, where the problem is - what do you want to do or achieve with
    your "modally looping Form on the other thread"?

    Please describe your whole context:
    - what you want to do with that Form on its separate new thread
    - and what you want to do with that Form from within your Main-Thread
    (Drawing- and "Data-Exchange"-wise).

    Olaf

  35. #35

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,

    First thank you for the reply.
    I will tell you what I want clearly.

    I am sending you universal threading zip file as attachment.
    It contains one vcdll project and vcexe project simple MFC based dialog based and dll using vc 6.0.

    The vcexe has one mainthread dialog having two buttons
    1. Display main dialog in newthread button

    2. Do background op in newthread button

    When you click on first button a form created in mainthread is displayed in new thread modally without blocking main thread.

    When you click on Second button sum is calculated in new thread without sum text box is updated in main thread.

    For doing both operations I am using a universal generic function

    void abc(UINT (*threadfuncptr)(LPVOID lp)) exported from vcdll.dll.
    The code for vcdll.dll is in vcdll project.

    So I require a universal vb6 dll similar to vcdll.dll which works for both displaying forms and doing
    background operations.It does'nt matter whether it exports one function for both background operations and forms display or two different functions for each.
    Attached Files Attached Files

  36. #36

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,
    Apart from my previous query can you also tell me how to use timeSetEvent api (Multimedia timers) in vb6 since the timer callback starts in a new thread.

  37. #37
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,687

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Quote Originally Posted by jsvenu View Post
    Dear Trick,

    Thank you for the clarification.
    You are able to create real thread in vb using your own vbcreatethread.
    I have read your many articles in vb using win32 API.
    Now I understand you have done many things in vb using code to implement assembly
    language using apis like copymemory,createthread etc.
    But the only difference I noticed is just like VC++ (unmanaged code ie.,win32,MFC,ATL)
    in VB6 we cannot do pure multithreading using GUI elements like forms.
    For example in VC++ MFC we can create a class say sdf derived from CDialog and
    create an object in one main thread say
    xyzdlg g_xyzdlg;
    and
    call g_xyzdlg.DoModal()
    in another thread say newthread without blocking main thread.
    Here g_xyzdlg owner will be newthread even though it is created in main thread.
    ie. the message loop of g_xuzdlg is in newthread but not in main
    thread.I am attaching a simple dialog based MFC project as attachment using vc++ 6.0.
    I think this is not possible in VB6 with or without marshalling .
    Is there any way to change form behaviour like this using any assembly language and win32
    or Free threading using FTM(Free Threaded Marshaller) or so or API or hooks or subclassing using pure vb6.
    I shall be grateful to you if you can provide a solution.
    Possible. If you don't need the marshaling, just don't use it. Just create the form in new thread:
    Code:
    Public Function NewThreadProc(value As threadst) As Long
        Dim frm As Form1
        
        Set frm = New Form1
        
        frm.Show 1
        
    End Function
    If you want to call a method of this form from the main thread, use marshaling.
    In the attached project you can call the method of the Form1 from the main thread without blocking. I use the Timer for the anynch call, but better if you'll use PostMessage.
    BTW, read the my articles more carefully, because in the first part i already had described this method, but with PostMessage and even there you can compare the asynch and synch calling.
    Attached Files Attached Files

  38. #38
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Quote Originally Posted by jsvenu View Post
    Dear Trick,
    Apart from my previous query can you also tell me how to use timeSetEvent api (Multimedia timers) in vb6 since the timer callback starts in a new thread.
    The quickest workaround in VB6 is that the callback needs to use a typelib'd POSTMESSAGE API, to post a message back to the Main thread.
    the PostMessage has to be typelib declared without usesgetlasterror, so it doesn't trigger VB's runtime error saving of API Calls, because the VB runtime has not been initialized on the callback thread.
    then you have to catch the message by either subclassing an existing window (from a form, or the parent window), or you can manually create a new message only window.

  39. #39

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2015
    Posts
    356

    Re: Displaying a form using Graphicsdll.vbp with testGraphicsdll.vbp(Code from The Tr

    Dear Trick,

    As I told about universal threading I have exe in which I create form object.
    I have universal dll in which I access the form using marshalling.
    Here because dll is different project and exe is another project I don't have the option of creating the form in exe
    in a thread in the dll because both are different.
    The main problem is that when a form object is created in vb in main thread the forms's owner is the main thread.
    so when i access the form using marshalling in new thread and show form modally thru forms method abc the main thread form is blocked
    even when i use timer or postmessage because both forms are in same thread.

    Is there any way to change the forms ownership from one thread to another so that i can use universal dll in which i create new thread and display the
    form modally without blocking the main form in main thread.

  40. #40

Page 1 of 4 1234 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