Page 1 of 2
Cross Platform MessageRequester
Posted: Wed May 30, 2012 9:39 pm
by Frarth
While searching the PB forum I noticed that there is not very much to find on a cross platform MessageRequester. Most examples are for windows only, while those developing on Linux have to do more of the hard work themselves (like showing icons). So I picked some examples and wrote some simple code to provide a cross platform MessageRequester. Any suggestions are welcome.
Include file ExtMessageRequester.pbi
Code: Select all
; Extended Message Requester include file (p) 2012 Frarth
; ------------------------------------------------------------------
EnableExplicit
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
#GTK_BUTTONS_YESNOCANCEL = 6
#MR_BUTTON_YES = #GTK_RESPONSE_YES
#MR_BUTTON_NO = #GTK_RESPONSE_NO
#MR_BUTTON_CANCEL = #GTK_RESPONSE_CANCEL
#MR_ICON_ERROR = #GTK_MESSAGE_ERROR * $200
#MR_ICON_INFORMATION = #GTK_MESSAGE_INFO * $200
#MR_ICON_QUESTION = #GTK_MESSAGE_QUESTION * $200
#MR_ICON_WARNING = #GTK_MESSAGE_WARNING * $200
CompilerElse
#MR_BUTTON_YES = #PB_MessageRequester_Yes
#MR_BUTTON_NO = #PB_MessageRequester_No
#MR_BUTTON_CANCEL = #PB_MessageRequester_Cancel
#MR_ICON_ERROR = #MB_ICONERROR
#MR_ICON_INFORMATION = #MB_ICONINFORMATION
#MR_ICON_QUESTION = #MB_ICONQUESTION
#MR_ICON_WARNING = #MB_ICONWARNING
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Declare GTK_MessageRequester(Title.s, Message.s, Buttons.l = #GTK_BUTTONS_OK, Type.l = #GTK_MESSAGE_INFO, Sub1.s = "", Sub2.s = "")
CompilerEndIf
Declare.i MessageRequesterX(Title.s, Message.s, Flags.l = 0)
Module ExtMessageRequester.pb
Code: Select all
; Extended MessageRequester (p) 2012 Frarth
; ----------------------------------------------------
EnableExplicit
XIncludeFile "ExtMessageRequester.pbi"
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Procedure GTK_MessageRequester(Title.s, Message.s, Buttons.l = #GTK_BUTTONS_OK, Type.l = #GTK_MESSAGE_INFO, Sub1.s = "", Sub2.s = "")
Protected *dialog.GtkMessageDialog
Protected result.i
*dialog = gtk_message_dialog_new_(0, #True, Type, Buttons, Message, Sub1, Sub2)
gtk_window_set_title_(*dialog, Title)
If Buttons = #GTK_BUTTONS_YESNOCANCEL
gtk_dialog_add_button_(*dialog, #GTK_STOCK_CANCEL, #GTK_RESPONSE_CANCEL)
gtk_dialog_add_button_(*dialog, #GTK_STOCK_NO, #GTK_RESPONSE_NO)
gtk_dialog_add_button_(*dialog, #GTK_STOCK_YES, #GTK_RESPONSE_YES)
EndIf
result = gtk_dialog_run_(*dialog)
gtk_widget_destroy_(*dialog)
ProcedureReturn result
EndProcedure
CompilerEndIf
Procedure.i MessageRequesterX(Title.s, Message.s, Flags.l = 0)
Protected buttons.l, result.l, type.l
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Select Flags & $1FF
Case #PB_MessageRequester_YesNo
buttons = #GTK_BUTTONS_YES_NO
Case #PB_MessageRequester_YesNoCancel
buttons = #GTK_BUTTONS_YESNOCANCEL
Case #PB_MessageRequester_Ok
buttons = #GTK_BUTTONS_OK
EndSelect
; TYPE
type = Flags / $200
result = GTK_MessageRequester(Title, Message, buttons, type)
CompilerElse ; Windows, Mac
result = MessageRequester(Title, Message, Flags)
CompilerEndIf
ProcedureReturn result
EndProcedure
; Example
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
gtk_init_(0,0)
CompilerEndIf
Define response.i
response = MessageRequesterX("Test", "Are you sure you want to use this stuff?", #PB_MessageRequester_YesNoCancel | #MR_ICON_QUESTION)
If response = #MR_BUTTON_YES
Debug "That is a YES!"
ElseIf response = #MR_BUTTON_NO
Debug "No, too bad."
Else
Debug "Please make up your mind!"
EndIf
Re: Cross Platform MessageRequester
Posted: Wed May 30, 2012 9:59 pm
by IdeasVacuum
I think it's necessary to to reorganise CompilerCase. As-is, cannot compile on Windows (#GTK constants not defined, structure GtkMessageDialog not defined etc.)
Re: Cross Platform MessageRequester
Posted: Thu May 31, 2012 6:49 am
by Frarth
Thanks for the input. Will redo my homework.

Re: Cross Platform MessageRequester
Posted: Thu May 31, 2012 7:10 am
by ts-soft
There is a problem on linux. I can press any button of the requester, the result is always: "Please make up your mind!"
(Ubuntu 12.04 x64)
// edit
The problem occurs only on x64!
Re: Cross Platform MessageRequester
Posted: Thu May 31, 2012 8:29 am
by Frarth
I don't have the ability to test on x64!
Have you debugged the output? It should generate three different results.
Please let me know if you've found a solution.
Re: Cross Platform MessageRequester
Posted: Thu May 31, 2012 8:44 am
by ts-soft
Here the fixed version.
changed:
- some variable types to long
- added compilerdirectives to run under macos and windows
Code: Select all
; Extended MessageRequester (p) 2012 Frarth
; -------------------------------------------------------
EnableExplicit
#GTK_BUTTONS_YESNOCANCEL = 6
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
#MR_BUTTON_YES = #GTK_RESPONSE_YES
#MR_BUTTON_NO = #GTK_RESPONSE_NO
#MR_BUTTON_CANCEL = #GTK_RESPONSE_CANCEL
#MR_ICON_ERROR = #GTK_MESSAGE_ERROR * $200
#MR_ICON_INFORMATION = #GTK_MESSAGE_INFO * $200
#MR_ICON_QUESTION = #GTK_MESSAGE_QUESTION * $200
#MR_ICON_WARNING = #GTK_MESSAGE_WARNING * $200
CompilerDefault
#MR_BUTTON_YES = #PB_MessageRequester_Yes
#MR_BUTTON_NO = #PB_MessageRequester_No
#MR_BUTTON_CANCEL = #PB_MessageRequester_Cancel
#MR_ICON_ERROR = #MB_ICONERROR
#MR_ICON_INFORMATION = #MB_ICONINFORMATION
#MR_ICON_QUESTION = #MB_ICONQUESTION
#MR_ICON_WARNING = #MB_ICONWARNING
CompilerEndSelect
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Procedure GTK_MessageRequester(Title.s, Message.s, Buttons.l = #GTK_BUTTONS_OK, Type.l = #GTK_MESSAGE_INFO, Sub1.s = "", Sub2.s = "")
Protected *dialog.GtkMessageDialog
Protected result.i
*dialog = gtk_message_dialog_new_(0, #True, Type, Buttons, Message, Sub1, Sub2)
gtk_window_set_title_(*dialog, Title)
If Buttons = #GTK_BUTTONS_YESNOCANCEL
gtk_dialog_add_button_(*dialog, #GTK_STOCK_CANCEL, #GTK_RESPONSE_CANCEL)
gtk_dialog_add_button_(*dialog, #GTK_STOCK_NO, #GTK_RESPONSE_NO)
gtk_dialog_add_button_(*dialog, #GTK_STOCK_YES, #GTK_RESPONSE_YES)
EndIf
result = gtk_dialog_run_(*dialog)
gtk_widget_destroy_(*dialog)
ProcedureReturn result
EndProcedure
CompilerEndIf
Procedure.i MessageRequesterX(Title.s, Message.s, Flags.l = 0)
Protected buttons.l, result.l, type.l
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
Select Flags & $1FF
Case #PB_MessageRequester_YesNo
buttons = #GTK_BUTTONS_YES_NO
Case #PB_MessageRequester_YesNoCancel
buttons = #GTK_BUTTONS_YESNOCANCEL
Case #PB_MessageRequester_Ok
buttons = #GTK_BUTTONS_OK
EndSelect
; TYPE
type = Flags / $200
result = GTK_MessageRequester(Title, Message, buttons, type)
CompilerDefault ; Windows, Mac
result = MessageRequester(Title, Message, Flags)
CompilerEndSelect
ProcedureReturn result
EndProcedure
;- Example
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
gtk_init_(0,0)
CompilerEndIf
Define response.i
response = MessageRequesterX("Test", "Are you sure you want to use this stuff?", #PB_MessageRequester_YesNoCancel | #MR_ICON_QUESTION)
If response = #MR_BUTTON_YES
Debug "That is a YES!"
ElseIf response = #MR_BUTTON_NO
Debug "No, too bad."
Else
Debug "Please make up your mind!"
EndIf
Greetings - Thomas
Re: Cross Platform MessageRequester
Posted: Thu May 31, 2012 8:49 am
by Frarth
I have updated the code snippet above. It should work fine on Windows now (tested on Windows XP SP3).
So LONG should be used instead of INTEGER on x64.
Re: Cross Platform MessageRequester
Posted: Thu May 31, 2012 8:53 am
by Frarth
Thanks for testing Thomas!
Re: Cross Platform MessageRequester
Posted: Thu May 31, 2012 8:56 am
by ts-soft
Frarth wrote:So LONG should be used instead of INTEGER on x64.
No, the best is integer, but if you make some bitshifting (<< >>) or bitwise or (&), you have to use
the required type (mostly long)
Re: Cross Platform MessageRequester
Posted: Thu May 31, 2012 8:59 am
by Frarth
Got it!
Re: Cross Platform MessageRequester
Posted: Sat Jun 02, 2012 2:02 am
by Guimauve
Hello everyone,
This my vision of the Frarth's original code :
Code: Select all
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Extended Message Requester
; File Name : Extended Message Requester.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : Guimauve
; Date : 01-06-2012
; Last Update : 01-06-2012
; PureBasic code : 4.61
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Notes :
;
; Extended Message Requester include file
; 2012 Frarth
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
#GTK_BUTTONS_YESNOCANCEL = 6
#MR_BUTTON_YES = #GTK_RESPONSE_YES
#MR_BUTTON_NO = #GTK_RESPONSE_NO
#MR_BUTTON_CANCEL = #GTK_RESPONSE_CANCEL
#MR_ICON_ERROR = #GTK_MESSAGE_ERROR * $200
#MR_ICON_INFORMATION = #GTK_MESSAGE_INFO * $200
#MR_ICON_QUESTION = #GTK_MESSAGE_QUESTION * $200
#MR_ICON_WARNING = #GTK_MESSAGE_WARNING * $200
Procedure GTK_MessageRequester(Title.s, Message.s, Buttons.l = #GTK_BUTTONS_OK, Type.l = #GTK_MESSAGE_INFO, Sub1.s = "", Sub2.s = "")
Protected *dialog.GtkMessageDialog, result.i
Static OneShot.b
If OneShot = #False
gtk_init_(0,0)
OneShot = #True
EndIf
*dialog = gtk_message_dialog_new_(0, #True, Type, Buttons, Message, Sub1, Sub2)
gtk_window_set_title_(*dialog, Title)
If Buttons = #GTK_BUTTONS_YESNOCANCEL
gtk_dialog_add_button_(*dialog, #GTK_STOCK_YES, #GTK_RESPONSE_YES)
gtk_dialog_add_button_(*dialog, #GTK_STOCK_NO, #GTK_RESPONSE_NO)
gtk_dialog_add_button_(*dialog, #GTK_STOCK_CANCEL, #GTK_RESPONSE_CANCEL)
EndIf
result = gtk_dialog_run_(*dialog)
gtk_widget_destroy_(*dialog)
ProcedureReturn result
EndProcedure
CompilerElse
#MR_BUTTON_YES = #PB_MessageRequester_Yes
#MR_BUTTON_NO = #PB_MessageRequester_No
#MR_BUTTON_CANCEL = #PB_MessageRequester_Cancel
#MR_ICON_ERROR = #MB_ICONERROR
#MR_ICON_INFORMATION = #MB_ICONINFORMATION
#MR_ICON_QUESTION = #MB_ICONQUESTION
#MR_ICON_WARNING = #MB_ICONWARNING
CompilerEndIf
; Extended MessageRequester (p) 2012 Frarth
; ----------------------------------------------------
Procedure.i MessageRequesterEx(Title.s, Message.s, Flags.l = 0)
Protected buttons.l, result.l, type.l
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Select Flags & $1FF
Case #PB_MessageRequester_YesNo
buttons = #GTK_BUTTONS_YES_NO
Case #PB_MessageRequester_YesNoCancel
buttons = #GTK_BUTTONS_YESNOCANCEL
Case #PB_MessageRequester_Ok
buttons = #GTK_BUTTONS_OK
EndSelect
result = GTK_MessageRequester(Title, Message, buttons, Flags / $200)
CompilerElse ; Windows, Mac
result = MessageRequester(Title, Message, Flags)
CompilerEndIf
ProcedureReturn result
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< !!! WARNING - YOU ARE NOW IN A TESTING ZONE - WARNING !!! <<<<<
; <<<<< !!! WARNING - THIS CODE SHOULD BE COMMENTED - WARNING !!! <<<<<
; <<<<< !!! WARNING - BEFORE THE FINAL COMPILATION. - WARNING !!! <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Select MessageRequesterEx("Test", "Are you sure you want to use this stuff?", #PB_MessageRequester_YesNoCancel | #MR_ICON_QUESTION)
Case #MR_BUTTON_YES
Debug "That is a YES!"
Case #MR_BUTTON_NO
Debug "No, too bad."
Case #MR_BUTTON_CANCEL
Debug "Please make up your mind!"
EndSelect
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Best regards
Guimauve
Re: Cross Platform MessageRequester
Posted: Sat Jun 02, 2012 6:31 am
by Frarth
Looks nice, only you forgot to remove the type.l variable declaration in MessageRequesterEx.
I put constant, structure, procedure declarations etc. in include files because my apps always have this set up:
Code: Select all
;- include files for public declarations (no procedure definitions here)
;- app flow
;- include modules including private declarations (all procedure definitions here)
That is why I got things separated.

Re: Cross Platform MessageRequester
Posted: Sat Oct 03, 2015 5:33 pm
by Keya
Great thread, thankyou everyone for contributions!:)
The following is a mashup mostly based on code in this thread but also some by wilbert to add Mac OSX support. (
NOW it's "Cross Platform" heehee

)
Ive called this MsgAlert() ... a simple (simplicity/minimal over flexibility) cross-platform messagebox with an OK button, and your choice of Information, Warning, or Error icon (easily extended).
Code: Select all
EnableExplicit
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Global Workspace.i = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
#MB_ICONINFORMATION = $40
#MB_ICONWARNING = $30
#MB_ICONERROR = $10
CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
#MB_ICONINFORMATION = #GTK_MESSAGE_INFO
#MB_ICONWARNING = #GTK_MESSAGE_WARNING
#MB_ICONERROR = #GTK_MESSAGE_ERROR
CompilerEndIf
Procedure.i ToAscii(inbuf$) ;required for Linux unicode-compiled version
Protected *outbuf = AllocateMemory(Len(inbuf$)+1)
If *outbuf
PokeS(*outbuf, inbuf$, -1, #PB_Ascii) ;perhaps this should be #PB_Utf8 seeing as thats what the Linux one wants
EndIf
ProcedureReturn *outbuf
EndProcedure
Procedure MsgAlert (hWnd.i, Title.s, Message.s, MB_ICON.i) ;Supports #MB_ICONINFORMATION, #MB_ICONERROR, #MB_ICONWARNING
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
MessageBox_(hWnd, Message, Title, #MB_OK + MB_ICON)
CompilerElseIf #PB_Compiler_OS = #PB_OS_MacOS ;based on example by wilbert
Protected Type.s, Alert.i = CocoaMessage(0, CocoaMessage(0, 0, "NSAlert new"), "autorelease")
Select MB_ICON
Case #MB_ICONWARNING: Type.s = "'caut'"
Case #MB_ICONERROR: Type.s = "'stop'"
Default: Type.s = "'note'"
EndSelect
CocoaMessage(0, CocoaMessage(0, Alert, "window"), "setParentWindow:", hWnd)
CocoaMessage(0, Alert, "setMessageText:$", @Title)
CocoaMessage(0, Alert, "setInformativeText:$", @Message)
CocoaMessage(0, Alert, "setIcon:", CocoaMessage(0, Workspace, "iconForFileType:$", @Type))
CocoaMessage(0, Alert, "runModal")
CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux ;based on example by Frarth & Guimauve
Protected *dlgmsgbox.GtkMessageDialog, result.i, Sub1.i, Sub2.i, pMsg.i, pTitle.i
pMsg = ToAscii(Message): pTitle = ToAscii(Title)
*dlgmsgbox = gtk_message_dialog_new_(hWnd, #True, MB_ICON, #GTK_BUTTONS_OK, pMsg, Sub1, Sub2)
gtk_window_set_title_(*dlgmsgbox, pTitle)
result = gtk_dialog_run_(*dlgmsgbox)
gtk_widget_destroy_(*dlgmsgbox)
CompilerEndIf
EndProcedure
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
gtk_init_(0,0)
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
InitCommonControls_()
CompilerEndIf
Define hWnd.i = 0 ;#HWND_DESKTOP
MsgAlert(hWnd, "My INFO!", "My message line 1" + Chr($D) + Chr($A) + "Line 2", #MB_ICONINFORMATION) ;$0A, $0D, and $0D0A all work fine on all 3 OS for messageboxes in my tests
MsgAlert(hWnd, "My ERROR!", "My message line 1" + Chr($D) + "Line 2", #MB_ICONERROR)
MsgAlert(hWnd, "My WARNING!", "My message line 1" + Chr($A) + "Line 2", #MB_ICONWARNING)
It supports Windows + Linux + Mac, 32 + 64, Ascii + Unicode, but i had to add the ToAscii function to support unicode-compiled Linux... is there a better way?
Re: Cross Platform MessageRequester
Posted: Tue Oct 06, 2015 5:12 pm
by Oma
Hi
@Frarth and Keya
sorry, i'm a little late, i know, but time is rare!
A few words to your Linux versions:
To show not only the first letters on the Requester texts, buttons and window title on Unicode OR no Umlauts with Ascii use proper Imports. All textes must be in UTF8-format.
@Keya: to get a feedback if more then 1 button is shown, make a
ProcedureReturn of the '
result'-variable AND this 'result' AND the function type must be '
long' for proper return on Linux-64Bit.
Two examples:
http://www.chabba.de/Linux/Requester/Me ... p_Modal.pb
http://www.chabba.de/Linux/Requester/Me ... unction.pb
Best Regards
Charly
Re: Cross Platform MessageRequester
Posted: Tue Oct 06, 2015 5:37 pm
by Keya
Oma wrote:@Keya: to get a feedback if more then 1 button is shown...
just for this 'MsgAlert' function i was aiming purely for simplicity and minimal code over flexibility, so just the one OK button and i intentionally stripped the responder out as it
seemed i could, being single button
I will get around to rewriting it for flexibility at a later stage, and will certainly be using your examples, thankyou!

but before that, next on my Todo list is get accustomed to using p-ascii/p-utf8 as we prepare for Unicode-only PB

I want to feel comfortable using Ascii from Unicode-compiled, but ive still got a lot more learning to do there. But I am more than willing to put in the time, because it feels good to overcome these hurdles, and then i can get on programming with "the whole ascii/unicode thing" being a tool instead of an obstruction. I hope
