A few API/UI questions
A few API/UI questions
[Content removed at author's request]
-
- Posts: 1706
- Joined: May 27, 2005 6:34
- Location: Cambodia, Thailand, Lao, Ireland etc.
- Contact:
Re: A few API/UI questions
EDIT: Double post of same mesage in error
Garvan
Garvan
Last edited by Sisophon2001 on Sep 16, 2005 14:29, edited 3 times in total.
-
- Posts: 1706
- Joined: May 27, 2005 6:34
- Location: Cambodia, Thailand, Lao, Ireland etc.
- Contact:
Re: A few API/UI questions
Hey, my I keep getting errors when I try posting, or editing posts, and my message is having children before my eyes. If this does not work I am leaving it be.
Garvan
Garvan
Last edited by Sisophon2001 on Sep 16, 2005 14:20, edited 1 time in total.
-
- Posts: 1706
- Joined: May 27, 2005 6:34
- Location: Cambodia, Thailand, Lao, Ireland etc.
- Contact:
Re: A few API/UI questions
UseZ!re wrote:How do you make a program "minimize to tray"?
Shell_NotifyIcon()
UseZ!re wrote:How do you check if a program is already running?
FindWindow()
UseZ!re wrote:How do you force focus on a process other than the one started?
SetForegroundWindow()
See sample code for details
Garvan
Code: Select all
''References: BCX sample code, FB hello.bas
option explicit
#include once "windows.bi"
#include once "win\shellapi.bi"
const WM_SHELLNOTIFY = WM_USER + 5
const ID_FB = 1001
const ID_EXIT = 1002
declare function WinMain ( byval hInstance as HINSTANCE, byval hPrevInstance as HINSTANCE, _
szCmdLine as string, byval iCmdShow as integer ) as integer
dim shared note as NOTIFYICONDATA
dim shared TB_CREATED as integer
dim shared szAppName as string
dim shared MainMenu as HANDLE
dim shared FileMenu as HANDLE
end WinMain( GetModuleHandle( null ), null, command$, SW_NORMAL )
function WndProc ( byval hWnd as HWND, byval message as UINT, byval wParam as WPARAM, _
byval lParam as LPARAM ) as LRESULT
static pt as point
function = 0
select case (message)
case WM_CREATE
TB_CREATED = RegisterWindowMessage ("TaskbarCreated")
exit function
case WM_DESTROY
UnregisterClass (szAppName, GetModuleHandle( null ))
Shell_NotifyIcon (NIM_DELETE, @note)
PostQuitMessage( 0 )
exit function
case WM_COMMAND
if LOWORD (wParam)= ID_FB then
Messagebox (0,"Hello from FreeBasic", "Sample", 0)
end if
if LOWORD (wParam) = ID_EXIT then
DestroyWindow (hWnd)
end if
case WM_CREATE
TB_CREATED = RegisterWindowMessage ("TaskbarCreated")
case WM_SHELLNOTIFY
if lParam = WM_RBUTTONDOWN then
GetCursorPos (@pt)
SetForegroundWindow (hWnd)
TrackPopupMenuEx (FileMenu, TPM_LEFTALIGN or TPM_RIGHTBUTTON, pt.x, pt.y, hWnd, NULL)
PostMessage (hWnd, WM_NULL, 0, 0)
end if
case TB_CREATED
Shell_NotifyIcon (NIM_ADD, @note)
end select
function = DefWindowProc( hWnd, message, wParam, lParam )
end function
function WinMain ( byval hInstance as HINSTANCE, _
byval hPrevInstance as HINSTANCE, _
szCmdLine as string, _
byval iCmdShow as integer ) as integer
dim wMsg as MSG
dim wcls as WNDCLASS
dim hWnd as HWND
function = 0
szAppName = "TrayApp"
hWnd=FindWindow(szAppName,NULL)
if hWnd <> 0 then
SetForegroundWindow(hWnd)
exit function
end if
with wcls
.style = CS_HREDRAW or CS_VREDRAW
.lpfnWndProc = @WndProc
.cbClsExtra = 0
.cbWndExtra = 0
.hInstance = hInstance
.hIcon = LoadIcon( NULL, IDI_APPLICATION )
.hCursor = LoadCursor( NULL, IDC_ARROW )
.hbrBackground = GetStockObject( WHITE_BRUSH )
.lpszMenuName = NULL
.lpszClassName = strptr( szAppName )
end with
if( RegisterClass( @wcls ) = FALSE ) then
MessageBox( null, "This program requires Windows NT!", szAppName, MB_ICONERROR )
exit function
end if
'' Create the window and _BUT DONT_ show it
hWnd = CreateWindowEx( 0, szAppName, "", _
0, _
0, 0, 0, 0, _
NULL, NULL, _
hInstance, _
NULL )
note.cbSize = sizeof (NOTIFYICONDATA)
note.hWnd = hWnd
note.hIcon = LoadIcon (NULL, MAKEINTRESOURCE (IDI_QUESTION))
note.uFlags = NIF_ICON or NIF_TIP or NIF_MESSAGE
note.uCallbackMessage = WM_SHELLNOTIFY
note.szTip= szAppName
Shell_NotifyIcon (NIM_ADD, @note)
MainMenu = CreateMenu ()
FileMenu = CreateMenu ()
AppendMenu (FileMenu, MF_STRING, ID_FB, "&FreeBASIC")
AppendMenu (FileMenu, MF_STRING, ID_EXIT, "E&xit")
InsertMenu (MainMenu, 0, MF_POPUP, FileMenu, "invisible menu")
while( GetMessage( @wMsg, NULL, 0, 0 ) <> FALSE )
TranslateMessage( @wMsg )
DispatchMessage( @wMsg )
wend
function = wMsg.wParam
end function
-
- Posts: 360
- Joined: Jun 07, 2005 20:59
- Location: england, somewhere around the middle
- Contact:
wow! i allways wanted to put a notifyicon on the taskbar, but i was looking through MSDN in circular ways (ie func1 needs a result from func2.... which needs a result from func1...), it's a good thing you didn't go looking in that maze! thx Sisophon2001! (+ i assume you use a standard icon, do you know how you use a custom one, eg "arbatraryicon.ico" instead?)
Am i right in thinking windows.bi is in the CVS release..... hmm maybe thins example is incentive enough for me to learn how to use CVS...
Many thx,
Joe :)
Am i right in thinking windows.bi is in the CVS release..... hmm maybe thins example is incentive enough for me to learn how to use CVS...
Many thx,
Joe :)
-
- Posts: 1706
- Joined: May 27, 2005 6:34
- Location: Cambodia, Thailand, Lao, Ireland etc.
- Contact:
You need to use a resource file (text file with .rc extension) with a single line naming your icon.
123 ICON DISCARDABLE "mario.ico"
And then change the code that loads the IDI_QUESTION icon, telling it the id number of your icon (123 in this case).
''note.hIcon = LoadIcon (NULL, MAKEINTRESOURCE (IDI_QUESTION))
note.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(123) )
Finally compile your program with the resource file
fbc.exe" -s gui "trayicon.bas" "trayicon.rc"
I think I saw that mjs posted a link to a testing version with the new headers included? Not sure now.
Have fun
Garvan
123 ICON DISCARDABLE "mario.ico"
And then change the code that loads the IDI_QUESTION icon, telling it the id number of your icon (123 in this case).
''note.hIcon = LoadIcon (NULL, MAKEINTRESOURCE (IDI_QUESTION))
note.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(123) )
Finally compile your program with the resource file
fbc.exe" -s gui "trayicon.bas" "trayicon.rc"
I think I saw that mjs posted a link to a testing version with the new headers included? Not sure now.
Have fun
Garvan
-
- Posts: 1706
- Joined: May 27, 2005 6:34
- Location: Cambodia, Thailand, Lao, Ireland etc.
- Contact:
Hi:
The code I posted minimizes to tray. The problem may be different versions of FB. This code needs the latest headers. To make it behave as you described would require only a few changes. I think I hid the window, and you want to hide/show it on demand.
But be Warned!
This is not going to work with a simple console program or a simple SCREEN program. If I really tried I might be able to do something with a native SCREEN program, but it would still be WinAPI code. You need access to the message loop, regardless of how you go about things, and the easiest way to do that is to write your own, rather than let FB do it for you.
The problem with this simple statement is that it takes a lot of work to learn the WinAPI, I would say it took me three or four days, 8 to 10 hours per day going through Petzold’s Programming Windows before I had an idea of how it all worked. And then I spend the next five years using it, which helps.
Are you still interested?
Garvan
The code I posted minimizes to tray. The problem may be different versions of FB. This code needs the latest headers. To make it behave as you described would require only a few changes. I think I hid the window, and you want to hide/show it on demand.
But be Warned!
This is not going to work with a simple console program or a simple SCREEN program. If I really tried I might be able to do something with a native SCREEN program, but it would still be WinAPI code. You need access to the message loop, regardless of how you go about things, and the easiest way to do that is to write your own, rather than let FB do it for you.
The problem with this simple statement is that it takes a lot of work to learn the WinAPI, I would say it took me three or four days, 8 to 10 hours per day going through Petzold’s Programming Windows before I had an idea of how it all worked. And then I spend the next five years using it, which helps.
Are you still interested?
Garvan
In FreeBASIC 0.15b, you can use a NULL GfxLib driver with SCREEN ("-1" in the options parameter), and then copy the data to a window you've set up with the WinAPI SetDIBits() and a BitmapV4Header format. There's an example of this in that screensaver kit I posted in the projects section.
You can get the hWnd from a GfxLib screen, but the WndProc is a different story. It might be a simple task to add "Minimize/Maximize/Restore" INKEY events to GfxLib's message loop though.
You can get the hWnd from a GfxLib screen, but the WndProc is a different story. It might be a simple task to add "Minimize/Maximize/Restore" INKEY events to GfxLib's message loop though.
Re: A few API/UI questions
Use SetForegroundWindow() ??Z!re wrote: How do you force focus on a process other than the one started?
Not recommended - M$ doesn't like it, and puts lots of obstacles between your feet, see http://msdn.microsoft.com/library/defau ... window.asp
What works always is the
ShowWindow(h&,SW_MINIMIZE)
ShowWindow(h&,SW_RESTORE)
combination.
You're asking a very unorthodox question. This took forever to figure out, but you'd have hijack GfxLib's WindowProc function and check for the necessary events.
Then, to minimize to tray you have to:
1) "Animate" the Window minimizing to tray with AnimateRect
2) Hide the Window with ShowWindow
3) Add the tray icon
Then, to show the tray
1) Stick the app back into the taskbar with ShowWindow
2) "Restore" it with SendMessage
3) Delete the tray icon
Pretty good learning experience. Anyways:
Then, to minimize to tray you have to:
1) "Animate" the Window minimizing to tray with AnimateRect
2) Hide the Window with ShowWindow
3) Add the tray icon
Then, to show the tray
1) Stick the app back into the taskbar with ShowWindow
2) "Restore" it with SendMessage
3) Delete the tray icon
Pretty good learning experience. Anyways:
Code: Select all
Option Explicit
#include "windows.bi"
#include "win/shellapi.bi"
#define WM_SHELLNOTIFY WM_USER + 5
' Some defines and typedefs for the Win32Driver structure
#define WINDOW_TITLE_SIZE 128
#define WINDOW_CLASS_PREFIX "fbgfxclass_"
Type BLITTER As Sub(As uByte Ptr, As Integer)
' Structure containing GfxLib's internal Windows info
Type Win32Driver
Version As Integer
hInstance As HINSTANCE
WndClass As WNDCLASS
Wnd As HWND
Palette(0 To 255) As PaletteEntry
Blitter As Blitter Ptr
Is_Running As Integer
Is_Palette_Changed As Integer
Is_Active As Integer
w As Integer
h As Integer
Depth As Integer
FullScreen As Integer
Refresh_Rate As Integer
Window_Title As uByte Ptr
WindowClass(0 To WINDOW_TITLE_SIZE + Len(WINDOW_CLASS_PREFIX)-1) As uByte
Init As Function() As Integer
Exit As Function() As Integer
Paint As Function() As Integer
Thread As Sub(ByVal Running_Event As HANDLE)
End Type
' Make that structure available
Extern FB_Win32 Alias "fb_win32" As Win32Driver
Declare Function WindowProc(ByVal hWnd As HWND, ByVal Message As uInteger, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As LRESULT
Screen 13
' Hijack Gfxlib's window procedure
Dim Shared OldWindowProc As WNDPROC
OldWindowProc = FB_Win32.WndClass.lpfnWndProc
SetWindowLong FB_Win32.Wnd, GWL_WNDPROC, @WindowProc
' Set up our notify icon
Dim Shared NotifyIcon As NOTIFYICONDATA
With NotifyIcon
.cbSize = SizeOf (NOTIFYICONDATA)
.hWnd = FB_Win32.Wnd
.hIcon = LoadIcon (NULL, MAKEINTRESOURCE (IDI_QUESTION))
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.uCallbackMessage = WM_SHELLNOTIFY
.szTip = "Yay Tooltips!"
End With
' Put some stuff on the screen
Do Until Inkey = Chr(255) + "X"
Pset(Rnd * 320, Rnd * 200), Rnd * 255
Loop
Function WindowProc(ByVal hWnd As HWND, ByVal Message As uInteger, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As LRESULT
Dim rcWindow As RECT
Dim rcTray As RECT
Dim hWndTaskBar As HWND
Dim hWndTray As HWND
Select Case As Const Message
Case WM_SYSCOMMAND
If wParam = SC_MINIMIZE Then
' Get the system tray's hWnd
hWndTaskBar = FindWindow("Shell_TrayWnd", NULL)
hWndTray = FindWindowEx(hWndTaskBar, 0, "TrayNotifyWnd", NULL)
' Show the notify icon
Shell_NotifyIcon (NIM_ADD, @NotifyIcon)
' Animate the window closing to the tray
GetWindowRect hWnd, @rcWindow
GetWindowRect hwndTray, @rcTray
DrawAnimatedRects hWnd, IDANI_CAPTION, @rcWindow, @rcTray
' Hide the window
ShowWindow(hWnd, SW_HIDE)
Return False
End If
Case WM_SHELLNOTIFY
If lParam = WM_LBUTTONDBLCLK Then
' Restore the window
ShowWindow(hWnd, SW_SHOWMINIMIZED)
SendMessage hWnd, WM_SYSCOMMAND, SC_RESTORE,0
' Hide the notify icon
Shell_NotifyIcon (NIM_DELETE, @NotifyIcon)
End If
End Select
' Let GfxLib then do it's own thing
Return OldWindowProc(hWnd, Message, wParam, lParam)
End Function