Announcement

Collapse
No announcement yet.

"Windowless" controls, Hwnd, Handle (not quite Inter-process)

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

  • "Windowless" controls, Hwnd, Handle (not quite Inter-process)

    I tag this with (not quite Inter-process) since my dll is part of the parent code when loaded so maybe "Inner-Process" is a better term? Anyways.....

    I have a dll, that a couple functions report back to the parent language to a textbox some data during long processes, which works well with languages that I can pass a Hwnd (or Handle) of the textbox for my function to report back to.

    I declared the function parameter as Long (probably should've made it DWORD) but anyways, here is the problem.

    Some Languages I find out that the textbox is "Windowless" (I have absolutely NO knowledge in that area) and I am told I can NOT get a handle or Hwnd in the parent language to pass to my my dll for my dll to report back to the parent.

    In this case I thought of maybe "WM_SETTEXT" (But SendMessage needs an Hwnd), and I thought of "RegisterWindowMessage" (But unsure if a "Windowless" language would even respond)....So I ask if anyone here has experience with this "Windowless" idea and could offer some help how I could either build a routine into the parent program, or in my dll to achieve communication?

    The other is in C where the Hwnd for the textbox is declared as "HWND MyTextBox", but I can not find how to use whatever this pointer, or Hwnd, or whatever could be used (I cant even figure out how to display it in a messagebox for that matter)....So Again I ask if anyone knows how and can help?

    In either case, I asked in the forums for that language (unfortunately no matter how many times I explain that the dll is NOT an OCX, that I got "Oh use this property/method/some ActiveX routine" that I do not use (nor would want to).....So I take it to the masses, and the wealth of knowledge from PB'ers that I know many of you come from backgrounds in other languages, or at least use PB where your "preferred" language "falls short" in some areas.

    Any help or ideas I have not thought of would be greatly appreciated. To date, normally if stuck with this kind of problem, I document the function as not available in whatever language I can not make work. Although this one seemed to rear its ugly head and I now find a situation that my function could easily solve (If I only knew how that is)

    Engineer's Motto: If it aint broke take it apart and fix it

    "If at 1st you don't succeed... call it version 1.0"

    "Half of Programming is coding"....."The other 90% is DEBUGGING"

    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

  • #2
    Do I have this right Cliff? You have an exported procedure in your dll which requires a hWnd parameter (to a textbox in the dll's client) to be passed 'in' by the client?

    If that's the case and your dll is usable in a non-windows environment (console mode?), why not just create an optional exported proc that the user needs to call to get progress info if he/she wants it? The client can then do what he/she wants with it.

    Why all the secrecy about this 'other' language? What is it?
    Fred
    "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

    Comment


    • #3
      actually my dll is awaiting the Handle or Hwnd (or forgive my lack of knowledge here), but the parent language being C or my arch-Nemisis..."LABVIEW" (WHO <insert explative here> can program with pictures? much less less 90 minutes and 4 monitors wide for a simple "For loop"???)

      (Sorry....I went on a tangent there...)

      Whatever the language (I am sure I will draw fire from MCM here...but at least now I understand why)...shouldnt there be a way that your dll can be used in anothers language of choice? (if given the right basic parameters)

      In my case I am attempting to make my PB dll accessible to all languages I can, but will admit that I can not learn enough of each to be the "Go between" in all cases
      Engineer's Motto: If it aint broke take it apart and fix it

      "If at 1st you don't succeed... call it version 1.0"

      "Half of Programming is coding"....."The other 90% is DEBUGGING"

      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

      Comment


      • #4
        I'm thinking then, that you need to program for the LCD (least common denominator) , which, would be a bare console screen. In that case, if the end game is notifications to the user of progress towards some goal or achievement of that goal, then use a window if the user is capable of creating one, and a console screen if otherwise. While I've never created a console window in a dll, I see no reason why it can't be done. Here a couple months ago I became infatuated with the idea of loading the C runtime library with PowerBASIC and using printf for console output. That is immenantly doable. I'll hunt up the link if you want. Basically, its a matter of calling the Api function AllocConsole() and outputting text to the console screen created. This can either be done with WriteConsole() or printf (from C runtime). Below is the event handler from a windows program in PowerBASIC (button click procedure) that creates the console...

        Code:
        Function fnWndProc_OnCommand(wea As WndEventArgs) As Long
          If LoWrd(wea.wParam)=%IDC_BUTTON1 And HiWrd(wea.wParam)=%BN_CLICKED Then
             Local hStdOutput As Dword              'Standart Output Handle
             Local hf,ptrFile As FILE Ptr           'FILE *
             Local hDll,hCrt As Dword
             Local hSysMenu As Dword
             Register i As Long
             hDll=LoadLibrary("msvcrt.dll")         'Load/Increment Reference Count on msvcrt.dll
             If hDll Then                           'Get base address of exported symbol _iob from msvcrt.dll.  _iob is an
                ptrFile=GetProcAddress(hDll,"_iob") 'array of FILE structs that holds the stdin, stdout, and stderr handles.
                Call AllocConsole()                 'These handels are zeroed out at initialization of a GUI process, and
                hSysMenu=GetSystemMenu(GetConsoleWindow(),ByVal 0)   'must be reset with valid operating system handles if
                Call DeleteMenu(hSysMenu,6,%MF_BYPOSITION)           'console output is desired in a GUI process.  With a
                hCrt=Open_OSFileHandle(GetStdHandle(%STD_OUTPUT_HANDLE),%O_TEXT)  'valid handel to stdout returned in hf, it
                hf=FDOpen(hCrt,"w")                 'is restored back in position 1 of the i/o buffer FILE array with
                @ptrFile[1][email protected]                     '@[email protected] printf output using CRT in PowerBASIC!
                Call PlayWithStrings()
                Call FreeLibrary(hDll)              'Free/decrement reference count on msvcrt.dll
             End If
          End If
        
          fnWndProc_OnCommand=0
        End Function
        If this might help, I'll hunt up that link. Let me know...
        Fred
        "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

        Comment


        • #5
          Here's a PB Win (GUI) program that creates a console and writes to the console with printf. It could be done in a conceptually easier manner with WriteConsole(), but why do something easy when a really 'geeky' difficult way exists? Perhaps you could implement this within your dll for those users using a tool which doesn't create a window?

          Code:
          'Program demonstrates how to restore standard output handle in C Runtime Library
          'which is zeroed out by initialization of GUI process.
          #Compile Exe
          #Include "Win32api.inc"           'Translation of Windows.h for PowerBASIC
          %IDC_BUTTON1 = 1250               'ctrl id of button
          %O_TEXT      = &H4000             'from Fcntl.h
          
          Type FILE      'From stdio.h      'When a GUI application is started the three standard OS handles
            pChar        As Asciiz Ptr      'STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE are all
            cnt          As Long            'zeroed out by the console initialization routines.  These three
            pBase        As Asciiz Ptr      'handles are replaced by valid values when a GUI application calls
            flag         As Long            'AllocConsole(). Therefore, once this is done, calling GetStdHandle()
            fil          As Long            'will always return valid handle values. The problem is that the
            charbuf      As Long            'CRT has already completed initialization before an application gets
            bufsize      As Long            'a chance to call AllocConsole(); the three low I/O handles 0, 1,
            TmpFileName  As Asciiz Ptr      'and 2 have already been set up to use the original zeroed out OS
          End Type                          'handles, so all CRT I/O is sent to invalid OS handles and CRT output
                                            'does not appear in the console.
          
          Declare Function GetConsoleWindow Lib "Kernel32.dll" Alias "GetConsoleWindow" () As Dword
          
          
          Declare Function printf CDecl Lib "msvcrt.dll" Alias "printf" _   'printf from stdio.h
          ( _
            szFmtStr As Asciiz _
            [, _
               Byval lpVar1 As Any, _
               Byval lpVar2 As Any, _
               Byval lpVar3 As Any, _
               Byval lpVar4 As Any _
            ] _
          ) As Long
          
          
          Declare Function Open_OSFileHandle CDecl Lib "msvcrt.dll" Alias "_open_osfhandle" _  'from IO.h
          ( _
            Byval hHandle As Long, _
            Byval iType   As Long _
          ) As Long
          
          
          Declare Function FDOpen CDecl Lib "msvcrt.dll" Alias "_fdopen" _   'from stdio.h
          ( _
            Byval hHandle As Long, _
            ByRef pszStr As Asciiz _
          ) As Dword
          
          
          Function WndProc(Byval hWnd As Long,Byval wMsg As Long,Byval wParam As Long,Byval lParam As Long) As Long
            Select Case wMsg
              Case %WM_CREATE
                Local hButton As Dword
                Local hIns As Dword
                hIns=GetModuleHandle(Byval 0)
                hButton=CreateWindow("button","Show Console!",%WS_CHILD Or %WS_VISIBLE,110,65,200,25,hWnd,%IDC_BUTTON1,hIns,Byval 0)
                WndProc=0
                Exit Function
              Case %WM_COMMAND
                If Lowrd(wParam)=%IDC_BUTTON1 And HiWrd(wParam)=%BN_CLICKED Then
                   Local hStdOutput As Dword              'Standart Output Handle
                   Local hf,ptrFile As FILE Ptr           'FILE *
                   Local hDll,hCrt,dwWeight As Dword
                   Local hSysMenu As Dword
                   Register i As Long
                   hDll=LoadLibrary("msvcrt.dll")         'Load/Increment Reference Count on msvcrt.dll
                   If hDll Then                           'Get base address of exported symbol _iob from msvcrt.dll.  _iob is an
                      ptrFile=GetProcAddress(hDll,"_iob") 'array of FILE structs that holds the stdin, stdout, and stderr handles.
                      Call AllocConsole()                 'These handels are zeroed out at initialization of a GUI process, and
                      hSysMenu=GetSystemMenu(GetConsoleWindow(),Byval 0)   'must be reset with valid operating system handles if
                      Call DeleteMenu(hSysMenu,6,%MF_BYPOSITION)           'console output is desired in a GUI process.  With a
                      hCrt=Open_OSFileHandle(GetStdHandle(%STD_OUTPUT_HANDLE),%O_TEXT)  'valid handel to stdout returned in hf, it
                      hf=FDOpen(hCrt,"w")                 'is restored back in position 1 of the i/o buffer FILE array with
                      @ptrFile[1][email protected]                     '@[email protected] printf output using CRT in PowerBASIC!
                      dwWeight=210
                      For i=1 To 200                     '
                        printf("%d" + Chr$(9) + "My Name Is Fred And I Weigh %u Pounds!"+$Cr+$Lf,i,dwWeight)
                      Next i
                      Call FreeLibrary(hDll)              'Free/decrement reference count on msvcrt.dll
                   End If
                End If
                WndProc=0
                Exit Function
              Case %WM_DESTROY
                Call PostQuitMessage(0)
                WndProc=0
                Exit Function
            End Select
          
            WndProc=DefWindowProc(hWnd, wMsg, wParam, lParam)
          End Function
          
          Function WinMain(Byval hIns As Long, Byval hPrev As Long, Byval lpCL As Asciiz Ptr, Byval iShow As Long) As Long
            Local szBuffer As Asciiz * 64
            Local wc As WNDCLASSEX
            Local Msg As tagMsg
            Local hWnd As Dword
          
            szBuffer="Console_Output"                           : wc.lpszClAssName=Varptr(szBuffer)
            wc.lpfnWndProc=Codeptr(WndProc)                     : wc.cbSize=Sizeof(wc)
            wc.style=%CS_HREDRAW Or %CS_VREDRAW                 : wc.hInstance=hIns
            wc.cbClsExtra=0                                     : wc.cbWndExtra=0
            wc.hIcon=LoadIcon(%NULL, Byval %IDI_APPLICATION)    : wc.hCursor=LoadCursor(%NULL, Byval %IDC_ARROW)
            wc.hbrBackground=%COLOR_BTNFACE+1                   : wc.lpszMenuName=%NULL
            Call RegisterClAssEx(wc)
            szBuffer="GUI Console Output With C Runtime Library From PowerBASIC!"
            hWnd=CreateWindow("Console_Output",szBuffer,%WS_OVERLAPPEDWINDOW,500,550,440,200,0,0,hIns,Byval 0)
            Call ShowWindow(hWnd,iShow)
            Call UpdateWindow(hWnd)
            While GetMessage(Msg,%NULL,0,0)
              TranslateMessage Msg
              DispatchMessage Msg
            Wend
          
            Function=msg.wParam
          End Function
          Fred
          "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

          Comment


          • #6
            ???

            If you need a window, why not just create one? Don't set WS_VISIBLE style and it won't show up. You can use a 'message only' window if you want.

            See: CreateWindow[Ex] in your Windows' API documentation.

            For that matter, if you are really hard up you can use the Desktop Window. (GetDesktopWindow() function).

            ???
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Yea, there's another idea (MCM's). Just RegisterClassEx() a plane jane window in DLL_PROCESS_ATTACH, then Create and/or output to that directly with TextOut()/DrawText(), or put a textbox/listbox on it and write text to that. At this point in time, how many users of your dll even know what a hwnd is? Most .NET programmers wouldn't, I don't think.
              Fred
              "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

              Comment


              • #8
                The Bigger question is, if you are calling functions requiring an 'hwnd', for what is 'hwnd' used?

                I think it a reasonable assumption that if the function wants an 'hWnd,' the function needs an 'hWnd' for something.

                (No, not always true, but certainly a reasonable starting point).

                MCM
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  >how many users of your dll even know what a hwnd is? Most .NET programmers wouldn't,
                  Using a Generic win32 in .NET is not a world-famous idea..
                  hellobasic

                  Comment


                  • #10
                    Windowless controls are a form of ActiveX control which do not have their own window. They are provided an area to draw themselves into by the container. In essence they draw themselves into someone elses window (what the container provides). At least that is how I read the API docs description. The specification for windowless controls dates back to 1996, amazinly, so its nothing really new.

                    Some interesting reading on MSDN seems to explain their value. Internet Explorer uses windowless controls to display web pages in the browser window. Windows (the OS) has a limit of how many true windows can be created at one time. By using a container and then windowless controls , real controls can be emulated in the browser so there is not a need to actually create real windows for all the controls on web pages. By using these emulations of real controls (windowless controls) the actual number of real controls is kept to a minimum.



                    Windowless controls are part of the OC96 (OLE controls 96) specification.
                    This specification likely gives details in how to communicate with these controls.

                    Windowless controls have advantages over real window windows. One that is noted is the ability to have the controls display have visual effects (like transparency) so they can merge well into a web page.

                    You may want to experiment using Visual Basic 6 and create some of your own "test" windowless controls. Then find a way to communicate between them and your PowerBasic DLL.



                    I have a feeling that COM may be needed, rather than just sending messages to a window class.

                    I don't have any experience with windowless control myself. I just gleaned the above from a quick search of MSDN and the API docs.
                    Chris Boss
                    Computer Workshop
                    Developer of "EZGUI"
                    http://cwsof.com
                    http://twitter.com/EZGUIProGuy

                    Comment


                    • #11
                      In most cases the user has no idea what a Hwnd is, but in this one case I need to get data back to the user while my dll is doing something else. For example

                      Code:
                      -------------------------
                      |                       |
                      |      LABVIEW VI       |
                      |                       |
                      |      -----------      |
                      |      | Textbox |<-----|<----
                      |      -----------      |    |
                      |                       |    |
                      |-----------------------|    |
                                 |                 |
                                 |                 |
                                 |                 |
                      -------------------------    |
                      |                       |    |
                      |         DLL           |    |
                      | Report to Textbox     |---->
                      |-----------------------|
                      where the Labview VI is none of my code, but I can post data to the textbox so the user can do whatever it is they are going to do with the data. So putting another Textbox in my dll does me not good.

                      Unless you mean put the textbox in my dll and have the other language "Poll" to see if the data changes?
                      Engineer's Motto: If it aint broke take it apart and fix it

                      "If at 1st you don't succeed... call it version 1.0"

                      "Half of Programming is coding"....."The other 90% is DEBUGGING"

                      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                      Comment


                      • #12
                        I don't have a solution for you, but do have some possible information. Microsoft created windowless controls mswless.ocx controls for VB. Windowless controls were originally created for IE and web page creation. A web page could have many object and if each object required a window, performance and resources would suffer



                        According to the MS docs windowsless controls use OLE instead of the normal messaging queues.

                        "Visual Basic 6.0 provides the capability of building Windowless controls, also known as lightweight controls. A new property of the UserControl, Windowless, enables this feature. Setting the Windowless property to True will make the UserControl Windowless, a control which sends and receives messages through OLE rather than the regular messaging queues that Windows uses."

                        Hope this helps.

                        Brian

                        Comment

                        Working...
                        X