Generally, using a subwindow to implement a floating toolbar is a good choice, but Photoshop is really abnormal. Its toolbar window can be removed from the customer area of the container window, how is it implemented? To sum up, the Photoshop floating toolbar has the following two features:
1. Like a common sub-window, clicking the toolbar does not change the activity status of the container window, And the toolbar window is always located at the upper layer of the container window.
2. However, unlike normal sub-Windows, toolbar windows are not restricted by the container window customer area and can be removed from the container window customer area.
It can be seen that the sub-window scheme does not work. Only the owner window scheme can be well implemented. The key is to set the window activity status, to ensure that the second feature can be perfectly implemented. The Code is as follows:
Option explicit <br/> '********************************* * **************************** <br/> '* program name: demo. bas <br/> '* program function: demonstrate how to create a floating window similar to Photoshop toolbar in VB <br/>' * Author: lyserver <br/> '* contact information: http://blog.csdn.net/lyserver <br/> '********************************** * *************************** <br/> private type wndclass <br/> style as long <br/> lpfnwndproc as long <br/> cbclsextra as long <br/> cbwndextra2 as long <br/> hinstance as long <br/> hicon as long <br/> hcursor as long <br/> hbrbackground as long <br/> lpszmenuname as string <br/> lpszclassname as string <br/> end type <br/> private declare Function registerclass lib "USER32" alias "registerclassa" (Class As wndclass) as long <br/> private const cs_vredraw as long = & H1 <br/> private const cs_hredraw as long = & H2 <br/> private const color_window as long = 5 <br/> private declare function unregisterclass lib "USER32" alias "unregisterclassa" (byval lpclassname as string, byval hinstance as long) As long <br/> private declare function createmediawex lib "USER32" alias "createmediawexa" (byval dwexstyle as long, byval lpclassname as string, byval lpwindowname as string, byval dwstyle as long, byval X as long, byval y as long, byval nwidth as long, byval nheight as long, byval hwndparent as long, byval hmenu as long, byval hinstance as long, lpparam as any) as long <br/> private const cw_usedefault as long = & h80000000 <br/> private const ws_overlappedwindow as long = & hcf0000 <br/> private const ws_child as long = & h40000000 <br /> private const ws_ex_toolwindow as long = & h80 <br/> private declare function updatewindow lib "USER32" (byval hwnd as long) as long <br/> private declare function showwindow lib "USER32" (byval hwnd as long, byval ncmdshow as long) as long <br/> private const sw_hide as long = 0 <br/> private const sw_shownormal as long = 1 <br/> private type rect <br/> left as long <br /> top as long <br/> right as long <br/> bottom as long <br/> end type <br/> private type pointapi <br/> X as long <br/> Y as long <br/> end type <br/> private declare function getclientrect lib "USER32" (byval hwnd as long, lprect as rect) As long <br/> private declare function clienttoscreen lib "USER32" (byval hwnd as long, lppoint as pointapi) as long <br/> private type MSG <br/> hwnd as long <br/> message as long <br/> wparam as long <br/> lparam as long <br/> time as long <br/> Pt as pointapi <br/> end type <br/> private declare function getmessage lib "USER32" alias "getmessagea" (lpmsg as MSG, byval hwnd as long, byval wmsgfiltermin as long, byval wmsgfiltermax as long) As long <br/> private declare function translatemessage lib "USER32" (lpmsg as MSG) as long <br/> private declare function dispatchmessage lib "USER32" alias "dispatchmessagea" (lpmsg as MSG) as long <br/> private const wm_close as long = & H10 <br/> private const wm_destroy as long = & H2 <br/> private const wm_ncactivate as long = & h86 <br /> private declare sub postquitmessage lib "USER32" (byval nexitcode as long) <br/> private declare function defwindowproc lib "USER32" alias "defwindowproca" (byval hwnd as long, byval wmsg as long, byval wparam as long, byval lparam as long) as long <br/> private declare function closewindow lib "USER32" (byval hwnd as long) As long <br/> private declare function destroywindow lib "USER32" (byval hwnd as long) as long <br/> private declare function sendmessage lib "USER32" alias "sendmessagea" (byval hwnd as long, byval wmsg as long, byval wparam as long, lparam as any) as long <br/> private declare function loadcursor lib "USER32" alias "loadcursora" (byval hinstance as long, byval lpcursorname as long) as long <br/> private const idc_arrow = 32512 & </P> <p> private m_howner as long, m_htool as long </P> <p> sub main () <br/> dim WC as wndclass <br/> dim umsg as MSG <br/> dim rtowner as rect, ptowner as pointapi </P> <p> 'register the window class <br/> WC. style = cs_vredraw or cs_hredraw <br/> WC. lpfnwndproc = getfuncaddr (addressof windowproc) <br/> WC. hinstance = app. hinstance <br/> WC. hcursor = loadcursor (0, idc_arrow) <br/> WC. hbrbackground = color_window <br/> WC. lpszclassname = "mywindowclass" </P> <p> If registerclass (WC) = 0 Then exit sub </P> <p> 'create owner window <br/> m_howner = create1_wex (0, WC. lpszclassname, "ownerwindow", _ <br/> ws_overlappedwindow, cw_usedefault, 0, 0, app. hinstance, byval 0 &) <br/> updatewindow m_howner <br/> showwindow m_howner, sw_shownormal </P> <p> 'obtain the coordinates of the upper left corner of the customer area of the owner window. <br/> getclientrect m_howner, rtowner <br/> ptowner. X = rtowner. left <br/> ptowner. y = rtowner. top <br/> clienttoscreen m_howner, ptowner </P> <p> 'create a window with the owner m_howner, the start position is in the upper left corner of the owner window. <br/> m_htool = create1_wex (ws_ex_toolwindow, WC. lpszclassname, "toolwindow", _ <br/> ws_overlappedwindow, ptowner. x, ptowner. y, 200, 55, m_howner, 0, app. hinstance, byval 0 &) <br/> updatewindow m_htool <br/> showwindow m_htool, sw_shownormal <br/> sendmessage m_htool, wm_ncactivate, 1, byval 0 & </P> <p> 'enters the message loop <br/> do while getmessage (umsg, 0, 0, 0) <> 0 <br/> translatemessage umsg <br/> dispatchmessage umsg <br/> loop </P> <p> 'cancel window class registration <br/> unregisterclass WC. lpszclassname, app. hinstance <br/> end sub </P> <p> function getfuncaddr (byval lpfuncaddr as long) as long <br/> getfuncaddr = lpfuncaddr <br/> end function </P> <p> function windowproc (byval hwnd as long, byval wmsg as long, byval wparam as long, byval lparam as long) as long <br/> select case wmsg <br/> case wm_close 'Close the window <br/> If hwnd = m_howner then <br/> destroywindow m_htool <br/> destroywindow m_howner <br/> end if <br/> case wm_ncactivate 'keep window activity status <br/> If wparam = 0 then <br/> sendmessage m_howner, wm_ncactivate, 1, byval 0 & <br/> exit function <br/> end if <br/> case wm_destroy 'ends the message loop <br/> If hwnd = m_howner then <br/> postquitmessage 0 <br/> exit function <br/> end if <br/> end select <br/> windowproc = defwindowproc (hwnd, wmsg, wparam, lparam) <br/> end function <br/>