Bay Six Software Forum Index Bay Six Software
Beyond the Basics
 
 FAQFAQ   SearchSearch   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

GUI skin (sort of)
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    Bay Six Software Forum Index -> WMLiberty DLL
View previous topic :: View next topic  
Author Message
Mattestion
New Member


Joined: 29 Feb 2012
Posts: 4

PostPosted: Feb 29th, 2012, 2:54am    Post subject: GUI skin (sort of) Reply with quote

I'm trying to use a bmp for the background of a window that will have controls. I've been able to do that but the problem I'm having is I can't close the window without using Ctrl+Alt+Del. Here is the code:

Code:

nomainwin

    open "WMLiberty" for dll as #wmlib

    loadbmp "skin", "bmp\skin.bmp"

    WindowWidth = 520
    WindowHeight = 400

    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)

    open "Skinned Window" for window_nf as #skin
    #skin "trapclose [QUIT]"

    callback lpfn, OnPaint ( ulong, ulong, ulong, ulong ), long

    hwndSkin = hwnd(#skin)

    calldll #wmlib, "SetWMHandler", _
        hwndSkin as ulong, _
        _WM_PAINT as ulong, _
        lpfn as ulong, _
        0 as long, _
        ret as long

    #skin "hide"
    #skin "show"


[LOOP]
    scan
    calldll #kernel32, "Sleep", _ 'Minimize CPU usage
        50 as long, _
        ret as void
    goto [LOOP]


[QUIT]
    close #skin
    close #wmlib
    end


function OnPaint(hwnd, uMsg, wParam, lParam)
    hdc = GetDC(hwnd)
    dcSkin = CreateCompatibleDC(hdc)
    r = SelectObject(dcSkin, hbmp("skin"))
    r = BitBlt(hdc, 0,0,520,400, dcSkin, 0, 0, _SRCCOPY)
    r = DeleteDC(dcSkin)
    r = ReleaseDC(hwnd, hdc)
    r = DeleteObject(hbmp("skin"))
end function

function GetDC(h)
    calldll #user32, "GetDC",_
        h as ulong,_ 'graphicbox handle
        GetDC as ulong 'returns handle to device context
end function

function ReleaseDC(h, hdc)
    calldll #user32, "ReleaseDC",_
        h as ulong,_    'window handle
        hdc as ulong,_  'device context
        ReleaseDC as long
end function

function DeleteDC(hDCM)
    calldll #gdi32, "DeleteDC", _
        hDCM as ulong, _
        DeleteDC as long
end function

function CreateCompatibleDC(hDC)
    calldll #gdi32, "CreateCompatibleDC", _
        hDC as ulong, _ 'current screen
        CreateCompatibleDC as ulong 'handle of memory DC
end function

function SelectObject(hDC,hImage)
    calldll #gdi32, "SelectObject", _
        hDC as ulong, _
        hImage as ulong, _
        SelectObject as ulong
end function

function DeleteObject(memBmp)
    calldll #gdi32, "DeleteObject", _
        memBmp as ulong, _
        DeleteObject as long
end function

function BitBlt(hDCdest, xDest, yDest, xWidth, yHeight, hDCsource, xSrc, ySrc, ROP)
    CallDll #gdi32, "BitBlt", _
        hDCdest as ulong,_ 'The destination DC
        xDest as long,_ 'x location on destination
        yDest as long,_ 'y location on destination
        xWidth as long,_ 'width to transfer
        yHeight as long,_ 'height to transfer
        hDCsource as ulong,_ 'The source DC
        xSrc as long,_ 'x location in source
        ySrc as long,_ 'y location in source
        ROP as ulong,_ 'The operation to be performed
        BitBlt as long 'nonzero if successful
end function


Here is a link to download the image: skin.bmp

_________________
Just BASIC v1.01 / Liberty BASIC Pro v4.04 / Run BASIC v1.01 / Vista Home Premium SP2 - AMD Athlon 64 X2 Dual Core Processor 5000+ 2.60 GHz - 2GB RAM
Back to top
View user's profile Send private message
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: Feb 29th, 2012, 11:23pm    Post subject: Re: GUI skin (sort of) Reply with quote

Mattestion wrote:
I'm trying to use a bmp for the background of a window that will have controls.

This may be a silly question, but have you tried the simple approach of using a graphics window? I know the docs say "They are not intended to contain controls" and "some controls do not work properly" but you may find that in practice they work fine. I believe I'm right in saying that in LB Βooster any control which works in a window of type 'Window' will also work in a window of type 'Graphics'.

Richard.
http://lbbooster.com/
Back to top
View user's profile Send private message Visit poster's website
Brent
Site Admin


Joined: 01 Jul 2005
Posts: 797

PostPosted: Mar 1st, 2012, 12:51am    Post subject: Re: GUI skin (sort of) Reply with quote

Hello and welcome,

Sorry about the slow response--bad thunderstorms here. Anyway, I think I found a way to do what you want.
Code:
struct ps,_ 'PAINTSTRUCT
    hdc as ulong, _
    fErase as long, _
    rcPaint.left as long, _
    rcPaint.top as long, _
    rcPaint.right as long, _
    rcPaint.bottom as long, _
    fRestore as long, _
    fIncUpdate as long, _
    rgbReserved as char[32]

    open "WMLiberty" for dll as #wmlib

    loadbmp "skin", "bmp\skin.bmp"

    WindowWidth = 520
    WindowHeight = 400

    UpperLeftX=int((DisplayWidth-WindowWidth)/2)
    UpperLeftY=int((DisplayHeight-WindowHeight)/2)

    open "Skinned Window" for window_nf as #skin
    #skin "trapclose [QUIT]"

    callback lpfn, OnPaint ( ulong, ulong, ulong, ulong ), long

    hwndSkin = hwnd(#skin)

    calldll #wmlib, "SetWMHandler", _
        hwndSkin as ulong, _
        _WM_PAINT as ulong, _
        lpfn as ulong, _
        0 as long, _
        ret as long

    Call EraseWindow hwnd(#skin)


[LOOP]
    scan
    calldll #kernel32, "Sleep", _ 'Minimize CPU usage
        50 as long, _
        ret as void
    goto [LOOP]


[QUIT]
    close #skin
    close #wmlib
    unloadbmp "skin"
    end


function OnPaint(hwnd, uMsg, wParam, lParam)
    hSkinBmp = hbmp("skin")
    dcSkin = CreateCompatibleDC(0)
    hOldBmp = SelectObject(dcSkin, hSkinBmp)
    CallDLL #user32, "BeginPaint", hwnd as ulong, ps as struct, ret as long
    r = BitBlt(ps.hdc.struct, 0,0,520,400, dcSkin, 0, 0, _SRCCOPY)
    CallDLL #user32, "EndPaint", hwnd as ulong, ps as struct, ret as long
    ret = DeleteObject(dcSkin)
 end function

function GetDC(h)
    calldll #user32, "GetDC",_
        h as ulong,_ 'graphicbox handle
        GetDC as ulong 'returns handle to device context
end function

function ReleaseDC(h, hdc)
    calldll #user32, "ReleaseDC",_
        h as ulong,_    'window handle
        hdc as ulong,_  'device context
        ReleaseDC as long
end function

function DeleteDC(hDCM)
    calldll #gdi32, "DeleteDC", _
        hDCM as ulong, _
        DeleteDC as long
end function

function CreateCompatibleDC(hDC)
    calldll #gdi32, "CreateCompatibleDC", _
        hDC as ulong, _ 'current screen
        CreateCompatibleDC as ulong 'handle of memory DC
end function

function SelectObject(hDC,hImage)
    calldll #gdi32, "SelectObject", _
        hDC as ulong, _
        hImage as ulong, _
        SelectObject as ulong
end function

function DeleteObject(memBmp)
    calldll #gdi32, "DeleteObject", _
        memBmp as ulong, _
        DeleteObject as long
end function

function BitBlt(hDCdest, xDest, yDest, xWidth, yHeight, hDCsource, xSrc, ySrc, ROP)
    CallDll #gdi32, "BitBlt", _
        hDCdest as ulong,_ 'The destination DC
        xDest as long,_ 'x location on destination
        yDest as long,_ 'y location on destination
        xWidth as long,_ 'width to transfer
        yHeight as long,_ 'height to transfer
        hDCsource as ulong,_ 'The source DC
        xSrc as long,_ 'x location in source
        ySrc as long,_ 'y location in source
        ROP as ulong,_ 'The operation to be performed
        BitBlt as long 'nonzero if successful
end function

Sub EraseWindow hWnd
    flags = _RDW_ERASE Or _RDW_INVALIDATE
    CallDLL #user32, "RedrawWindow", _
        hWnd  as ulong, _
        _NULL  as ulong, _
        _NULL as ulong, _
        flags as ulong, _
        ret   as long
End Sub

_________________
Brent
Back to top
View user's profile Send private message Send e-mail
Mattestion
New Member


Joined: 29 Feb 2012
Posts: 4

PostPosted: Mar 1st, 2012, 2:18am    Post subject: Re: GUI skin (sort of) Reply with quote

Thanks, that works perfectly. Could you explain to me why this method works?
_________________
Just BASIC v1.01 / Liberty BASIC Pro v4.04 / Run BASIC v1.01 / Vista Home Premium SP2 - AMD Athlon 64 X2 Dual Core Processor 5000+ 2.60 GHz - 2GB RAM
Back to top
View user's profile Send private message
STPendl
Full Member


Joined: 20 Aug 2007
Posts: 161
Location: Austria

PostPosted: Mar 1st, 2012, 8:32am    Post subject: Re: GUI skin (sort of) Reply with quote

The EraseWindow API function forces a WM_PAINT message.

You will better succeed, if you get some information about handling GUI windows in plain ANSI C without using any GUI framework.

_________________
Stefan

Any code I post can be freely used, just give credit.
Back to top
View user's profile Send private message
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: Mar 1st, 2012, 9:43am    Post subject: Re: GUI skin (sort of) Reply with quote

Mattestion wrote:
Thanks, that works perfectly.

Yes, it works in LBB too, somewhat to my surprise. What I don't understand, though, is why (in LB) you need this code instead of a simple wait:

Code:
[LOOP]
    scan
    calldll #kernel32, "Sleep", _ 'Minimize CPU usage
        50 as long, _
        ret as void
    goto [LOOP]

Substituting a wait appears to cause the program to ignore the trapclose and not to respond to the the close button. In LBB a wait works fine, but that's not surprising because internally it does exactly the same as the above loop (although it sleeps for only 1 ms).

And I still wonder what advantage this approach has over a graphics window. Is it true, as the docs imply, that some controls don't work properly, and if so which ones are they?

Richard.
Back to top
View user's profile Send private message Visit poster's website
STPendl
Full Member


Joined: 20 Aug 2007
Posts: 161
Location: Austria

PostPosted: Mar 1st, 2012, 10:02am    Post subject: Re: GUI skin (sort of) Reply with quote

The SCAN-loop is a requirement of using WMLiberty, so Brent will surly have the correct answer.

Static text controls do not work in a graphics control and some of the notifications for other controls are eaten by the graphics control, so the controls do not respond to user actions.

_________________
Stefan

Any code I post can be freely used, just give credit.
Back to top
View user's profile Send private message
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: Mar 1st, 2012, 11:29am    Post subject: Re: GUI skin (sort of) Reply with quote

STPendl wrote:
Static text controls do not work in a graphics control and some of the notifications for other controls are eaten by the graphics control, so the controls do not respond to user actions.

Ah, OK. I'll have to add that to the list of advantages of LBB, because it uses exactly the same window class for both GRAPHICS and WINDOW, so should handle control notifications the same way.

Richard.
Back to top
View user's profile Send private message Visit poster's website
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: Mar 1st, 2012, 4:33pm    Post subject: Re: GUI skin (sort of) Reply with quote

STPendl wrote:
Static text controls do not work in a graphics control.

Actually as far as I can see they do work, so long as you force an initial redraw (which you can do for example using a font command):

Code:
  statictext #main.st, " Static text ", 40, 40, 240, 60
  open "Statictext in a graphics window" for graphics_nsb as #main
  #main "down; backcolor blue; boxfilled 320 340; flush"
  #main.st "!font Arial 36"
  wait

However you can't change the colour, so that might be one reason why this isn't an acceptable approach.

Richard.
Back to top
View user's profile Send private message Visit poster's website
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: Mar 1st, 2012, 6:17pm    Post subject: Re: GUI skin (sort of) Reply with quote

STPendl wrote:
some of the notifications for other controls are eaten by the graphics control.

I haven't managed to find any notifications that are 'eaten' by the graphics window; this is the program I used:

Code:
  nomainwin

  array$(1) = "Some"
  array$(2) = "items"
  array$(3) = "for"
  array$(4) = "the"
  array$(5) = "Combobox"
  array$(6) = "and"
  array$(7) = "Listbox"

  button #main.button, "Button", Notify, UR, 40, 10
  checkbox #main.checkbox, "Checkbox", Notify, Notify, 10, 10, 120, 20
  combobox #main.combobox, array$(), Notify, 10, 50, 120, 130
  listbox #main.listbox, array$(), Notify, 160, 50, 120, 130
  radiobutton #main.radiobutton1, "Radiobutton 1", Notify, Notify, 10, 200, 120, 20
  radiobutton #main.radiobutton2, "Radiobutton 2", Notify, Notify, 160, 200, 120, 20

  open "Notifications in a graphics window" for graphics_nsb as #main
  #main "down; backcolor blue; boxfilled 320 340; flush"
  #main "trapclose [Quit]"
  wait

[Quit]
  close #main
  end

sub Notify handle$
  notice handle$
end sub

I wonder if this is yet another example of something which used to be the case in an earlier version of LB but no longer is, but the help file hasn't been updated.

Richard.
Back to top
View user's profile Send private message Visit poster's website
Brent
Site Admin


Joined: 01 Jul 2005
Posts: 797

PostPosted: Mar 1st, 2012, 10:07pm    Post subject: Re: GUI skin (sort of) Reply with quote

With respect to WAIT not working with callbacks, I can only guess the reason. I seem to recall that when callbacks were added, Carl said the functionality was in a Smalltalk library. It may be that that library makes some assumptions about how callbacks are used. There might be more than one event loop, or maybe there's a flag that the WAIT statement doesn't set which causes LB to ignore events when it is in "callback mode."
_________________
Brent
Back to top
View user's profile Send private message Send e-mail
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: Mar 3rd, 2012, 11:46am    Post subject: Re: GUI skin (sort of) Reply with quote

Brent wrote:
Code:
    ret = DeleteObject(dcSkin)
 end function

Shouldn't that be DeleteDC rather than DeleteObject?

Code:
    ret = DeleteDC(dcSkin)
 end function

Richard.
Back to top
View user's profile Send private message Visit poster's website
Brent
Site Admin


Joined: 01 Jul 2005
Posts: 797

PostPosted: Mar 3rd, 2012, 6:17pm    Post subject: Re: GUI skin (sort of) Reply with quote

RichardRussell wrote:
Shouldn't that be DeleteDC rather than DeleteObject?

http://msdn.microsoft.com/en-us/library/dd183489%28v=vs.85%29.aspx
In CreateCompatibleDC, MSDN wrote:
When you no longer need the memory DC, call the DeleteDC function. We recommend that you call DeleteDC to delete the DC. However, you can also call DeleteObject with the HDC to delete the DC.

_________________
Brent
Back to top
View user's profile Send private message Send e-mail
RichardRussell
Full Member


Joined: 28 Jan 2012
Posts: 57
Location: Downham Market, UK

PostPosted: Mar 3rd, 2012, 7:00pm    Post subject: Re: GUI skin (sort of) Reply with quote

Brent wrote:
In CreateCompatibleDC, MSDN wrote:
We recommend that you call DeleteDC to delete the DC. However, you can also call DeleteObject.

MSDN at its worst! If DeleteDC is recommended why would one ever use anything else? This wording (which is a recent addition) is possibly because current versions of Windows (2000 onwards) have accepted either, whereas earlier ones may have accepted only DeleteDC.

Richard.
Back to top
View user's profile Send private message Visit poster's website
Alyce
Full Member


Joined: 04 Jul 2005
Posts: 91

PostPosted: Mar 4th, 2012, 12:02pm    Post subject: Re: GUI skin (sort of) Reply with quote

RichardRussell wrote:
If DeleteDC is recommended why would one ever use anything else?
Richard.


Why not? DeleteObject works on many graphics objects, such as pen, brush, font, bitmap, region, and palette. The programmer only needs to remember the syntax for a single API call. Also, if APIs are wrapped in user-functions, one function is all that is needed and can be called many times.

That argument is off-topic for this thread, however. Brent did not make an error in his code and that is all that is pertinent to the OP.

Regarding Richard's message, "I haven't managed to find any notifications that are 'eaten' by the graphics window; this is the program I used: " I tried the code. I added to it and "setfocus" to the graphics window to trap user events. I added graphics statements to trap mouse events and keypresses. Even with the added focus and traps, the controls appeared to work correctly. It may be that the caveat against putting controls over graphics is no longer needed, but before I'd count on that, I'd try it with a graphicbox instead of a graphics window, and I'd test it on different versions of Windows. I never use a graphics window, other than for short demos. I use a graphicbox inside a regular window, which gives me more control and flexibility.

_________________
- Alyce
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Bay Six Software Forum Index -> WMLiberty DLL All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum



Lo-Fi Version
Powered by phpBB © 2001, 2005 phpBB Group