Results 1 to 14 of 14

Thread: How to skin other windows?

  1. #1

    Thread Starter
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088

    How to skin other windows?

    I tried to make a simple program to skin any window.. I used this code:
    Code:
        Dim DC As Long
        Dim hWnd As Long
        Dim Temp As Rect
        
        hWnd = Window(SelectedWindow).hWnd
        
        'Get rect
        GetClientRect hWnd, Temp
        DC = GetWindowDC(hWnd)
    
        'Setup rect
        Temp.Left = Temp.Left + 4
        Temp.Top = Temp.Top + 4
    
        Temp.Right = Temp.Right - Temp.Left + 4
        Temp.Bottom = Temp.Bottom - Temp.Top + 4
    
        'Copy picture
        With Temp: BitBlt DC, .Left, .Top, .Right, .Bottom, Front.hDC, 0, 0, vbSrcCopy: End With
    The code actually works, see the screenshot:


    However, can you help me with this?

    • How can I get the offset (4 in the example) from windows?
    • Any way to only paint into the BG of the window? (not over controls)
    • How to keep the picture there? (enabled "AutoRedraw" for that window)


    Thanks for ideas!
    Attached Images Attached Images  

  2. #2
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Interesting! Sounds like a good project!

    Maybe there's a child window for that code, eg. where the icons are. You could check by using the GetChildWindow API call (I believe).
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  3. #3
    Zaei
    Guest
    Use a big freakin while loop to check the color of a GetPixel(). If it is a certain color, SetPixelV from your skin image. It works wonders, but it is slow =(.

    I dont know if you can create a GDI brush that is an image, but if you can, do that, and use SetClassLong with GCL_HBRBACKGROUND, and the Brush handle =).

    I think that, to set AutoRedraw on a window, use Get- and SetClassLong, Get the current Style (GCL_STYLE), bit-or it with CS_SAVEBITS, and set it back.

    Z.

  4. #4

    Thread Starter
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088
    SetPixelling is too slow and the API cant handle pictures as brushed... and the SaveBits thingy wont work neither (tried it, just draws into the titlebar then..)


    Any other ideas?
    Last edited by Fox; Dec 3rd, 2001 at 08:49 AM.

  5. #5
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    Create a system wide message hook and override the paint messages? Would be a real challenge in VB

    Or, if you only want certain windows, you could try to override just the windowproc using SetWindowLong with GWL_WNDPROC, then draw your background whenever a paint message comes by... again, highly unstable in VB


    Either way, it's going to be tricky...



    Now for your list:


    "How can I get the offset (4 in the example) from windows?"

    Is there anything special with that offset that is the same for every window you want to paint? Are the controls that much off the border?


    "Any way to only paint into the BG of the window? (not over controls)"

    WM_ERASEBKGND ?


    "How to keep the picture there? (enabled "AutoRedraw" for that window)"

    If you override the paint procedures you can just redraw it every time, thus emulating the AutoRedraw thing...
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  6. #6

    Thread Starter
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088
    > Is there anything special with that offset that is
    > the same for every window you want to paint?
    > Are the controls that much off the border?"

    I just noticed a normal window's frame size is 4 pixels, but i'd rather get a distance from the registry 'coz the user might have changed it.


    > WM_ERASEBKGND ?

    With BitBlt?


    > If you override the paint procedures you can
    > just redraw it every time, thus emulating
    > AutoRedraw thing...

    Sounds good, but too instable to implement..

  7. #7
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    Originally posted by Fox
    I just noticed a normal window's frame size is 4 pixels, but i'd rather get a distance from the registry 'coz the user might have changed it.
    I think GetClientRect should get the correct size (excluding the border), although you use it and still have to add 4 pixels. Weird...


    Originally posted by Fox
    > WM_ERASEBKGND ?

    With BitBlt?
    The problem is, you can paint as much background as you want, unless your controls are transparant you won't see much

    With the 'My Computer' window, you can try to find the ListView and set a transparancy style (if it exists) or simply use the ListView for overriding the paint methods. For other windows it would be somewhat more difficult...


    Originally posted by Fox
    > If you override the paint procedures you can
    > just redraw it every time, thus emulating
    > AutoRedraw thing...

    Sounds good, but too instable to implement..
    I know, but I though I'd just let you know the way I would try to do it.... although I stopped thinking in VB terms a while ago


    [edit] typo
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  8. #8
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    The CreatePatternBrush function creates a logical brush with the specified bitmap pattern. The bitmap cannot be a DIB section bitmap, which is created by the CreateDIBSection function.

    HBRUSH CreatePatternBrush(

    HBITMAP hbmp // handle to bitmap
    );


    Parameters

    hbmp

    Identifies the bitmap to be used to create the logical brush.

    Windows 95: Creating brushes from bitmaps or DIBs larger than 8x8 pixels is not supported. If a larger bitmap is specified, only a portion of the bitmap is used.
    So it IS possible to use bitmap brushes, but they would be 8x8 max. on Win9x


    (I just love the Win32 SDK help files that came with Delphi )
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  9. #9
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    Sorry for yet another post, but I just found something interesting:


    The GetSystemMetrics function retrieves various system metrics and system configuration settings.

    System metrics are the dimensions (widths and heights) of Windows display elements. All dimensions retrieved by GetSystemMetrics are in pixels.

    int GetSystemMetrics(

    int nIndex // system metric or configuration setting to retrieve
    );


    nIndex

    Specifies the system metric or configuration setting to retrieve. All SM_CX* values are widths. All SM_CY* values are heights. The following values are defined:

    *cut*

    SM_CXBORDER,
    SM_CYBORDER The width and height, in pixels, of a window border. This is equivalent to the SM_CXEDGE value for windows with the 3-D look.

    So there's the answer to question #1
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  10. #10

    Thread Starter
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088
    Mhm, well..


    I quickly tried the SetPixel method, just to show you




    Damn slow but who cares..
    Attached Images Attached Images  

  11. #11
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    You dirty....
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  12. #12
    Zaei
    Guest
    Told you it looks sweet =). Youll never get a better skin effect with BitBlt =). Besides, it is applied to everything of the color selected =).

    Z.

  13. #13
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    You could get an image of the window (bitblt), try to get a DIB (that's the fast array thing right?) from it and bitblt it back after you've manipulated the array...

    Don't have a clue on how to do that though, never really needed it




    ...or you could download WindowBlinds
    (although that's not half as much fun )
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  14. #14

    Thread Starter
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088
    *hehe*

    Thanks all The array idea is great, when I find the time I'll give it a try. Probably some DMA with DDraw?

    I'll let you know as I have any demo

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