Tech Off Thread

20 posts

Slightly beyond Winforms and hopefully not beyond my ability...

Back to Forum: Tech Off
  • User profile image
    Cannot​Resolve​Symbol

    Would it be possible to take the client area of a window from another (unmanaged Win32) application and embed it inside a managed WinForms (.net 2.0) app?  Preferably in C# but if it can't be done there, it would be a good excuse for me to start working in C++.

  • User profile image
    SlackmasterK

    Sounds reasonable... If it's possible, it would probably require running a copy of that app within yours, then stripping out the unwanted portions.  Sorry, no idea how to do it.

  • User profile image
    Cannot​Resolve​Symbol

    SlackmasterK wrote:
    Sounds reasonable... If it's possible, it would probably require running a copy of that app within yours, then stripping out the unwanted portions.  Sorry, no idea how to do it.


    That's what I want to do...  except I just need to strip out the window decorations.  I don't need to be able to interact with it programatically, just to be able to determine its size (preferably) and start/stop it.

  • User profile image
    cheong

    CannotResolveSymbol wrote:

    That's what I want to do...  except I just need to strip out the window decorations.  I don't need to be able to interact with it programatically, just to be able to determine its size (preferably) and start/stop it.

    You may try FindWindow() then GetWindowDC then GetWindowExtEx()/GetWindowInfo(). I've not tried it, but sounds possible.

    Recent Achievement unlocked: Code Avenger Tier 4/6: You see dead program. A lot!
    Last modified
  • User profile image
    Yggdrasil

    CannotResolveSymbol wrote:
    Would it be possible to take the client area of a window from another (unmanaged Win32) application and embed it inside a managed WinForms (.net 2.0) app?  Preferably in C# but if it can't be done there, it would be a good excuse for me to start working in C++.


    I have a mostly-working sample of this I did a while ago - a .NET UserControl that can embed a running Win32 application in it.
    It's not perfect - it has problems with VB6 apps, Office apps and others that do tricks with their window handles - it basically uses the FindWindow, SetParent and SetWindowLong API calls to make the app a child window.

    If you want, I can look for it when I get home and send it over, or put it in the sandbox.

  • User profile image
    Khamul

    Any contribution to the Sandbox is a good contribution. Smiley

  • User profile image
    Cannot​Resolve​Symbol

    Yggdrasil wrote:
    CannotResolveSymbol wrote:Would it be possible to take the client area of a window from another (unmanaged Win32) application and embed it inside a managed WinForms (.net 2.0) app?  Preferably in C# but if it can't be done there, it would be a good excuse for me to start working in C++.


    I have a mostly-working sample of this I did a while ago - a .NET UserControl that can embed a running Win32 application in it.
    It's not perfect - it has problems with VB6 apps, Office apps and others that do tricks with their window handles - it basically uses the FindWindow, SetParent and SetWindowLong API calls to make the app a child window.

    If you want, I can look for it when I get home and send it over, or put it in the sandbox.


    If you could put it in the sandbox, that would be nice.

  • User profile image
    Cannot​Resolve​Symbol

    Okay, so I got Windows to set the parent of a window to my form (Calculator in this case), but I need to remove the title bar.  I've imported SetWindowLong like this:

    [DllImport("USER32.DLL")]
            public static extern long SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);

    to match it's (unmanaged) method signature:

    LONG SetWindowLong(
        HWND hWnd,
        int nIndex,
        LONG dwNewLong
    );

    But when I try to run it, it tells me that the call has imbalanced the stack, probably because the signatures don't match up.  I know it isn't the HWND that's the problem, because IntPtr worked for FindWindow and SetParent.  Is this LONG here equivalent to a different type in C#?

  • User profile image
    Cannot​Resolve​Symbol

    --post deleted, apparently pressed the wrong button when trying to edit--

  • User profile image
    Cannot​Resolve​Symbol

    Okay-- got the call to work.  It apparently wants a 32-bit long.  That makes it an int...  It still doesn't work right, though.  I'll try using 16 bits for the int there.

  • User profile image
    Mike Dimmick

    Yes, C++ int and long are both 32-bit, while C# int is 32-bit (maps to Int32) while long is 64-bit (maps to Int64). Both the dwNewLong parameter and the return type should be 'int' in the C# extern declaration.

  • User profile image
    footballism

    Mike Dimmick wrote:
    Yes, C++ int and long are both 32-bit, while C# int is 32-bit (maps to Int32) while long is 64-bit (maps to Int64). Both the dwNewLong parameter and the return type should be 'int' in the C# extern declaration.

    That's why I often use type names rather than type aliases:

    long l = 10000000000;
    int i = 10;

    Int64 l = 10000000000000;
    Int32 i = 10;

    Sheva

  • User profile image
    PerfectPhase

    I always find this a handy site

    http://pinvoke.net/default.aspx/user32/SetWindowLong.html

    Stephen.

  • User profile image
    Ion Todirel
  • User profile image
    Cannot​Resolve​Symbol

    I want to essentially embed an instance of an unmanaged app inside my .net app.  Since I don't know C++/Win32 well (as I've shown here), I can't modify the app to make it into a COM control or anything, so I'm just trying to get the client area of the app and place it inside my window (without decorations).  Here's my progress so far (using Calculator because the app which I'll be embedding later is too slow and heavy to test with):

    Free Image Hosting at www.ImageShack.us

    [edit] Forgot to say what the problem was...  if I don't use setWindowLong(), the window works fine, just like a normal window except bounded by the UserControl (grey area).  If I do, it shows the calculator like this, but it won't respond to the mouse and won't repaint again if a menu is moved over it or the form containing it is covered by something else.

    Here's the relevant code I'm using (I've taken the values for GWL_STYLE and WS_STYLE out of Windows.h and made them local constants).  Note that this requires that Calculator be started ahead of time, as I don't feel the need to start it in code yet:

    public void StartPearPC()
    {
        IntPtr par = this.Handle;
        IntPtr child = FindWindow("SciCalc", "Calculator");

        SetParent(child, par);
        SetWindowLong(child, GWL_STYLE, WS_CHILD);
    }

  • User profile image
    Sven Groot

    By doing that, you're clearing all existing styles from the window, which is not a good idea.

    Try this:
    int style = GetWindowLong(child, GWL_STYLE);
    SetWindowLong(child, GWL_STYLE, style | WS_CHILD);

  • User profile image
    Cannot​Resolve​Symbol

    OK-   thanks.  I'll try that.

  • User profile image
    Cannot​Resolve​Symbol

    Now the (Calculator) window works again as expected--  except that it still has a title bar...  what style do I use to turn it off?

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.