Code : Tout sélectionner
;;
; NotePB.pb : un "premier pas" pour un éditeur Notepad avec quelques limitations dans cette version, telle la limitation de la taille de chaines à 64K
;
; Ce code est envoyé sur le forum pour un usage pédagogique, il ne devrait pas être utilisé autrement sans l'accord de l'auteur.
; Il s'agit d'un logiciel faisant partie d'applications sous licence et non libre de droits.
; D'autres fonctions existent, ainsi qu'un interface utilisateur personnalisable sur demande à fweil@internext.fr.
;
; Ce code source PureBasic ne devrait pas s'exécuter correctement sur des plateformes non compatibles Windows, et exclusivement pour des utilisateurs disposant d'un environnement PureBasic sous licence.
;
; FWeil : 20040612
;
; Les commentaires sont proposés aux utilisateurs du forum PureBasic.
;
Enumeration
#EditorGadget
#MenuItem_New
#MenuItem_Open
#MenuItem_Save
#MenuItem_SaveAs
#MenuItem_Print
#MenuItem_Close
#MenuItem_Exit
#MenuItem_Find
#MenuItem_FindNext
#MenuItem_Replace
#MenuItem_Font
#MenuItem_Help
#MenuItem_Apropos
#MenuItem_Nono
#Window_Main
#StatusBar
#Menu
EndEnumeration
#TTS_RECTANGULAR = $10 ; Constantes API non prévues dans PureBasic pour la définition des bulles d'aide.
#TTS_RECTANGULARLIFT = $20
#TTS_BALLOON = $40
Global FileName.s, NLines.l, nchars.l, FontName.s, FontSize.l, FontColor.l, FontStyle.l
Procedure AddToolTip(Handle, Text.s) ; Ceci remplace la commande GadgetToolTip de PureBasic en donnant plus de possibilités pour ce type de gadget. Win32 API utilisée
hToolTip = CreateWindowEx_(0, "tooltips_class32", "", $D0000000 | #TTS_BALLOON, 0, 0, 0, 0, WindowID(#Window_Main), 0, GetModuleHandle_(0), 0) ; Création d'une bulle.
SendMessage_(hToolTip, #RB_SETTEXTCOLOR - 1, $C0FFFF, 0) ; Couleur d'avant-plan. Je sais pas pourquoi #RB_SETTEXTCOLOR - 1 !
SendMessage_(hToolTip, #RB_SETBKCOLOR, $400000, 0) ; Couleur d'arrière plan
SendMessage_(hToolTip, #RB_SIZETORECT + 1, 0, 180) ; Largeur max de la bulle. Je sais toujours pas pourquoi #RB_SIZETORECT + 1 !
Button.TOOLINFO\cbSize = SizeOf(TOOLINFO) ; Structure pour remplir la bulle
Button\uFlags = #TTF_IDISHWND | #TTF_SUBCLASS ; Indique que le membre uId est le handle. Si ce signal n'est pas mis, uId est l'identifiant de la bulle. | Indique que la bulle doit être sous classée pour récupérer des messages comme #WM_MOUSEMOVE. Si ce n'est pas précisé, il faudra utiliser le signal #TTM_RELAYEVENT pour envoyer les messages message au contrôle bulle. Pour une liste des messages utilisables par une bulle, voir #TTM_RELAYEVENT.
Button\hwnd = Handle
Button\uID = Handle
Button\lpszText = @Text
SendMessage_(hToolTip, #RB_SETBARINFO, 0, Button) ; Renvoie le contenu de la structure à la fenêtre bulle.
EndProcedure
Procedure SavePreferences(IniFileName.s)
If CreatePreferences(IniFileName)
WritePreferenceString("FontName", FontName)
WritePreferenceLong("FontSize", FontSize)
WritePreferenceLong("FontColor", FontColor)
WritePreferenceLong("FontStyle", FontStyle)
ClosePreferences()
EndIf
EndProcedure
Procedure MenuItemWithShortcut(MenuItem.l, ItemText.s, Shortcut.l) ; Procédure pour créer un item de menu et le raccourci correspondant.
MenuItem(MenuItem, ItemText)
AddKeyboardShortcut(#Window_Main, Shortcut, MenuItem)
EndProcedure
Procedure ClearAll() ; Efface le contenu du gadget editeur et les variables associées.
SetGadgetText(#EditorGadget, "")
FileName = ""
NLines = 0
nchars = 0
EndProcedure
Procedure HighlightSelection(Handle.l, a.l, b.l)
If a And b
SendMessage_(Handle, #EM_SETSEL, a, b) ; Envoie un message pour fixer la sélection au handle indiqué. C'est une commande API. Cela permet de mettre en surbrillance les caractères de a à b dans le gadget correspondant au handle.
SendMessage_(Handle, #EM_SCROLLCARET, 0, 0) ; Envoie un message pour faire défiler le contenu du gadget et positionner le curseur à un endroit donné.
EndIf
EndProcedure
Procedure SaveContent(ThisFileName.s) ; Vérifie si le contenu du gadget peut être sauvegardé et effectue la sauvegarde.
If CreateFile(0, ThisFileName)
If nchars <= 64000
WriteString(0,GetGadgetText(#EditorGadget))
CloseFile(0)
FileName = ThisFileName
Else
MessageRequester("Warning", "Save of more than 63999 chars is not possible", #PB_MessageRequester_Ok)
EndIf
Else
MessageRequester("Warning", "File " + ThisFileName + " creation not possible", #PB_MessageRequester_Ok)
EndIf
EndProcedure
Procedure MyStatusBar()
CreateStatusBar(#StatusBar, WindowID(#Window_Main))
AddStatusBarField(150)
AddStatusBarField(450)
EndProcedure
; Programme principal.
;
Procedure wndProc(WindowID, message, wParam, lParam)
Resultat = #PB_ProcessPureBasicEvents
Select message
Case #WM_SIZING ; Cet évènement est le redimensionnement de la fenêtre. #WM_SIZE est une constante API.
ResizeGadget(#EditorGadget, 10, 0, WindowWidth(#Window_Main) - 20, WindowHeight(#Window_Main) - 40) ; Modifie la taille du gadget.
FreeStatusBar(#StatusBar) ; Détruit la barre de status précédente et en recréé une.
MyStatusBar()
UpdateWindow_(WindowID)
EndSelect
ProcedureReturn Resultat
EndProcedure
FontName = "Verdana" ; Sélection d'une police existante.
FontSize = 12 ; Sélection d'une taille possible pour la police.
FontColor = #Black ; Une valeur RGB pour la couleur de la police. #Black est une constante PureBasic égale à 0.
FontStyle = 0 ; 0, #PB_Font_Bold, #PB_Font_Italic.
CR.s = Chr(13)
LF.s = Chr(10)
EOL.s = CR + LF
TAB.s = Chr(9)
CurrentDirectory.s = Space(#MAX_PATH) ; #MAX_PATH est une constante API qui donne la longueur maximale d'un chemin complet d'accès à un fichier (actuallement 260).
FileName = ""
GetCurrentDirectory_(#MAX_PATH, CurrentDirectory) ; Fixe CurrentDirectory au répertoire de démarrage du programme.
WorkingDirectory.s = CurrentDirectory ; Garde une copie de la valeur CurrentDirectory.
ProgramName.s = "NotePB 2" ; Utilisé dans le titre de la fenêtre et le nom du fichier .ini.
If OpenPreferences(ProgramName + ".ini") ; Tente de lire fichier ini ou en créé un s'il n'existe pas.
FontName = ReadPreferenceString("FontName", FontName)
FontSize = ReadPreferenceLong("FontSize", FontSize)
FontColor = ReadPreferenceLong("FontColor", FontColor)
FontStyle = ReadPreferenceLong("FontStyle", FontStyle)
ClosePreferences()
Else
SavePreferences(ProgramName + ".ini") ; Enregistre les paramètres d'initialisation.
EndIf
Quit.l = #False
hwnd.l = OpenWindow(#Window_Main, 0, 0, 320, 240, ProgramName, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
If hwnd
SetWindowCallback(@wndProc())
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Escape, #PB_Shortcut_Escape)
CreateGadgetList(hwnd)
SetGadgetFont(#PB_Default, LoadFont(0, FontName, FontSize, FontStyle)) ; Change la valeur de la police pour les gadgets.
hEditorGadget = EditorGadget(#EditorGadget, 10, 0, WindowWidth(#Window_Main) - 20, WindowHeight(#Window_Main) - 40) ; Créé un nouveau gadget.
AddToolTip(hEditorGadget, "Vous pouvez utiliser tous les raccourcis et menus" + EOL + "incluant également les raccourcis standards de Windows :" + EOL + "Couper (CTRL+X)" + EOL + "Copier (CTRL+C)" + EOL + "Coller (CTRL+V)" + EOL + "Tout sélectionner (CTRL+A)")
format.CHARFORMAT\cbSize = SizeOf(CHARFORMAT) ; Prépare les attributs de couleur dans la structure appropriée pour envoyer les informations au gadget.
format\dwMask = #CFM_COLOR ; Constante API. Le membre crTextColor et la valeur #CFE_AUTOCOLOR du membre dwEffects sont valides.
format\crTextColor = FontColor ; Couleur du texte. Ce membre est ignoré si #CFE_AUTOCOLOR est spécifié. Met à jour la police après appel du FontRequester.
SendMessage_(hEditorGadget, #EM_SETCHARFORMAT, 0, @format) ; Envoie l'information de couleur pour le gadget. Appel API.
CreateMenu(#Menu, hwnd) ; Créé le menu avec titres et items. ALT + première lettre active l'entrée d'un menu. En appuyant ensuite sur la lettre marquée, on accède à l'item.
MenuTitle("Fichier")
MenuItemWithShortcut(#MenuItem_New, "&Nouveau" + TAB + "CTRL+N", #PB_Shortcut_Control | #PB_Shortcut_N)
MenuItemWithShortcut(#MenuItem_Open, "&Ouvrir" + TAB + "CTRL+O", #PB_Shortcut_Control | #PB_Shortcut_O)
MenuItemWithShortcut(#MenuItem_Save, "&Sauver" + TAB + "CTRL+S", #PB_Shortcut_Control | #PB_Shortcut_S)
MenuItemWithShortcut(#MenuItem_SaveAs, "Sauver &Comme" + TAB + "MAJ+CTRL+S", #PB_Shortcut_Control | #PB_Shortcut_S | #PB_Shortcut_Shift)
MenuItemWithShortcut(#MenuItem_Print, "&Print" + TAB + "MAJ+CTRL+P", #PB_Shortcut_Control | #PB_Shortcut_P | #PB_Shortcut_Shift)
MenuItemWithShortcut(#MenuItem_Close, "&Fermer" + TAB + "CTRL+W", #PB_Shortcut_Control | #PB_Shortcut_W)
MenuBar()
MenuItemWithShortcut(#MenuItem_Exit, "&Terminer" + TAB + "CTRL+Q", #PB_Shortcut_Control | #PB_Shortcut_Q)
MenuTitle("Editer")
MenuItemWithShortcut(#MenuItem_Find, "&Chercher" + TAB + "CTRL+F", #PB_Shortcut_Control | #PB_Shortcut_F)
MenuItemWithShortcut(#MenuItem_FindNext, "Chercher &Suivant" + TAB + "F3", #PB_Shortcut_F3)
MenuItemWithShortcut(#MenuItem_Replace, "&Remplacer" + TAB + "CTRL+H", #PB_Shortcut_Control | #PB_Shortcut_H)
MenuTitle("Affichage")
MenuItemWithShortcut(#MenuItem_Font, "&Police" + TAB + "MAJ+CTRL+F", #PB_Shortcut_Control | #PB_Shortcut_F | #PB_Shortcut_Shift)
MenuTitle("Aide")
MenuItemWithShortcut(#MenuItem_Help, "&Aide" + TAB + "F1", #PB_Shortcut_F1)
MenuItemWithShortcut(#MenuItem_Apropos, "A&propos" + TAB + "F12", #PB_Shortcut_F12)
MenuTitle("Nono")
MenuItemWithShortcut(#MenuItem_Nono, "&Parle" + TAB + "F9", #PB_Shortcut_F9)
MyStatusBar()
Repeat ; Voici la boucle principale de gestion d'évènements. Elle est basée sur un WaitWindowEvent. Trois entrée principales sont données : #PB_Event_CloseWindow, #PB_Event_Menu et #WM_SIZE.
Select WaitWindowEvent()
Case #PB_Event_CloseWindow ; Commutateur Quit pour quitter le programme.
Quit = #True
Case #PB_Event_Menu ; Les évenements menus générés par le clavier avec les raccourcis, ou les accès aux menus sont traités ici.
Select EventMenu()
Case #MenuItem_New ; Génère un effacement du contenu du gadget éditeur et des variables associées.
ClearAll()
Case #MenuItem_Open ; Ouvre un fichier après avoir effacé le contenu du gadget éditeur. Remplit le gadget éditeur avec le contenu du fichier.
ClearAll()
FileName = OpenFileRequester("Choisir le fichier à ouvrir", WorkingDirectory + "\" + FileName, "*.*", 0)
If ReadFile(0, FileName)
Repeat
a$ = ReadString(0)
AddGadgetItem(#EditorGadget, NLines, a$)
NLines + 1 ; NLines et NChars sont des variables statistiques, mais servent également à la fonction recherche.
nchars + Len(a$) + 2
Until Eof(0)
CloseFile(0)
EndIf
Case #MenuItem_Save ; Enregistre le contenu du gadget éditeur dans le fichier précédemetn ouvert.
SaveContent(FileName)
Case #MenuItem_SaveAs ; Enregistre le contenu du gadget éditeur dans un fichier dont le nom est saisi par l'utilisateur.
SaveContent(SaveFileRequester("Choisir le nom du fichier à enregistrer", WorkingDirectory + "\" + FileName, "*.*", 0))
Case #MenuItem_Close ; Cette commande est redondante avec New.
ClearAll()
Case #MenuItem_Exit ; Commute cette variable de faux à vrai pour sortir du programme.
Quit = #True
Case #MenuItem_Find ; Demande à l'utilisateur un masque de recherche et positionne le contenu du gadget éditeur sur la première occurence trouvée.
Text.s = InputRequester("Trouver", "Entrez le texte à trouver", Text)
a$ = GetGadgetText(#EditorGadget)
b$ = ReplaceString(a$, EOL, LF)
StartPos = FindString(b$, Text, 1) - 1
HighlightSelection(hEditorGadget, StartPos, StartPos + Len(Text))
Case #MenuItem_FindNext ; Fait défiler le contenu du gadget à la prochaine occurence correspondant au masque de recherche. Cette recherche est circulaire. Si la fin du contenu est atteinte, on continue en reprenant au début.
a$ = GetGadgetText(#EditorGadget)
b$ = ReplaceString(a$, EOL, LF)
StartPos = FindString(b$ , Text, StartPos + Len(Text)) - 1 ; Trouve la position de la prochaine occurence
HighlightSelection(hEditorGadget, StartPos, StartPos + Len(Text))
Case #MenuItem_Replace ; Remplace toutes les occurences Text par ReplaceText dans le contenu du gadget éditeur.
Text.s = InputRequester("Remplacer", "Entrer le texte à trouver", Text)
ReplaceText.s = InputRequester("Remplacer", "Remplacer par", ReplaceText)
a$ = GetGadgetText(#EditorGadget)
b$ = ReplaceString(a$, Text, ReplaceText)
SetGadgetText(#EditorGadget, b$)
Case #MenuItem_Font ; Ouvre un sélecteur de polices avec les attributs étendus pour changer la police, les attributs et la couleur. Mauvaise donne pour la couleur, ça ne fonctionne pas pour l'instant.
FontRequester(FontName, FontSize, #PB_FontRequester_Effects)
FontName = SelectedFontName() ; Mise à jour du nom de la police.
If SelectedFontSize() ; Mise à jour de la taille. Optionnel au cas où l'on termine le sélecteur sans faire de choix.
FontSize = SelectedFontSize()
EndIf
FontColor = SelectedFontColor() ; Mise à jour de la couleur.
FontStyle = SelectedFontStyle() ; Mise à jour du style.
a$ = GetGadgetText(#EditorGadget) ; Il est nécessaire de détruire les gadgets, avant de les recréer avec les nouveaux attributs. il sera également nécessaire de recharger le fichier en cours dans le gadget éditeur.
FreeGadget(#EditorGadget) ; Destruction du gadget.
SetGadgetFont(#PB_Default, LoadFont(0, FontName, FontSize, FontStyle)) ; Changement de la police à utiliser.
hEditorGadget = EditorGadget(#EditorGadget, 10, 0, WindowWidth(#Window_Main) - 20, WindowHeight(#Window_Main) - 40) ; Création d'un nouveau gadget.
AddToolTip(hEditorGadget, "Vous pouvez utiliser tous les raccourcis clavier et menus" + EOL + "incluant également les raccourcis standards de Windows :" + EOL + "Couper (CTRL+X)" + EOL + "Copier (CTRL+C)" + EOL + "Coller (CTRL+V)" + EOL + "Tout sélectionner (CTRL+A)")
format.CHARFORMAT\cbSize = SizeOf(CHARFORMAT) ; Prépare les attributs de couleur dans la structure appropriée avant de les envoyer au gadget.
format\dwMask = #CFM_COLOR ; Constante API. Le membre crTextColor et la valeur #CFE_AUTOCOLOR du membre dwEffects sont valides.
format\crTextColor = FontColor ; Couleur du texte. Ce membre est ignoré si #CFE_AUTOCOLOR est spécifié. Met à jour la police après appel du FontRequester.
SendMessage_(hEditorGadget, #EM_SETCHARFORMAT, 0, @format) ; Envoie l'information de couleur pour le gadget. Appel API.
SetGadgetText(#EditorGadget, a$) ; Remplit le gadget avec le contenu précédement stocké.
Case #MenuItem_Help
HelpMessage.s = "NotePB 2 - Aide en ligne" + EOL
HelpMessage = HelpMessage + "" + EOL
HelpMessage = HelpMessage + "Vous pouvez utiliser les menus et raccourcis" + EOL
HelpMessage = HelpMessage + "" + EOL
HelpMessage = HelpMessage + "Fichier Nouveau = CTRL+N" + EOL
HelpMessage = HelpMessage + "Fichier Ouvrir = CTRL+O" + EOL
HelpMessage = HelpMessage + "Fichier Sauver = CTRL+S" + EOL
HelpMessage = HelpMessage + "Fichier Sauver Comme = MAJ+CTRL+S" + EOL
HelpMessage = HelpMessage + "Fichier Fermer = CTRL+W" + EOL
HelpMessage = HelpMessage + "Terminer = CTRL+Q" + EOL
HelpMessage = HelpMessage + "Chercher = CTRL+F" + EOL
HelpMessage = HelpMessage + "Chercher Suivant = F3" + EOL
HelpMessage = HelpMessage + "Remplacer= CTRL+H" + EOL
HelpMessage = HelpMessage + "Police = MAJ+CTRL+F" + EOL
HelpMessage = HelpMessage + "Aide = F1" + EOL
HelpMessage = HelpMessage + "Apropos = F12" + EOL
HelpMessage = HelpMessage + "" + EOL
HelpMessage = HelpMessage + "Vous disposez également des raccourcis 'classiques' :" + EOL
HelpMessage = HelpMessage + "" + EOL
HelpMessage = HelpMessage + "Couper (CTRL+X)" + EOL
HelpMessage = HelpMessage + "Copier (CTRL+C)" + EOL
HelpMessage = HelpMessage + "Coller (CTRL+V)" + EOL
HelpMessage = HelpMessage + "Tout sélectionner (CTRL+A)"
MessageRequester("NotePB 2 - Aide", HelpMessage, #PB_MessageRequester_Ok)
Case #MenuItem_Apropos
HelpMessage.s = "NotePB 2 - Apropos" + EOL
HelpMessage = HelpMessage + "" + EOL
HelpMessage = HelpMessage + "Créé par fweil@internext.fr" + EOL
HelpMessage = HelpMessage + "Cette version est NotePB 2 : publié le 2004/05/17" + EOL
HelpMessage = HelpMessage + "" + EOL
HelpMessage = HelpMessage + "Ce programme n'est pas un logiciel libre." + EOL
HelpMessage = HelpMessage + "Merci de nous contacter pour plus d'informations" + EOL
MessageRequester("NotePB 2 - Apropos", HelpMessage, #PB_MessageRequester_Ok)
Case #MenuItem_Print
If PrintRequester()
If StartPrinting("NotePad 2")
StartDrawing(PrinterOutput())
PrinterFontSize = FontSize * 3
PrinterFontHeight = 3 * PrinterFontSize / 2
PrinterDPI = 360
PrinterTopMargin = PrinterDPI
PrinterLeftMargin = PrinterDPI
PrintYLocation = PrinterTopMargin
PrintXLocation = PrinterLeftMargin
DrawingFont(LoadFont(23, FontName, PrinterFontSize, FontStyle))
BackColor(RGB(255, 255, 255))
FrontColor(FontColor)
DrawingMode(1)
For i = 0 To CountGadgetItems(#EditorGadget) - 1
PrintYLocation + PrinterFontHeight
DrawText(PrintXLocation, PrintYLocation,GetGadgetItemText(#EditorGadget, i, 0))
If PrintYLocation > 10 * PrinterDPI
NewPrinterPage()
PrintYLocation = PrinterTopMargin
EndIf
Next
StopDrawing()
StopPrinting()
EndIf
EndIf
Case #MenuItem_Nono
For i = 0 To CountGadgetItems(#EditorGadget) - 1
phrase.s=(GetGadgetItemText(#EditorGadget, i, 0))
If OpenLibrary(0, "nono2004.dll") And Len(phrase.s)>1
;************************
panoramique=125:; le son sera sur les 2 haut-parleurs (0 tout a gauche) (255 tout a droite)
Frequence=11025
CallFunction(0, "nono2004", phrase.s,Frequence,panoramique) ;appel la dll et lui passe la phrase a dire
EndIf
Next
Quit = #False
; CallFunction(0, "nono2004", "/." ,Frequence,panoramique) ;appel la dll et lui passe la phrase a dire
Case #PB_Shortcut_Escape ; Commute pour sortir du programme.
Quit = #True
Default
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #EditorGadget
*Buffer = AllocateMemory(64000)
Debug SendMessage_(hEditorGadget, #EM_GETSELTEXT, 0, *Buffer)
TextCapture.s = PeekS(*Buffer)
FreeMemory(*Buffer)
EndSelect
Case #WM_SIZING ; Cet évènement est le redimensionnement de la fenêtre. #WM_SIZE est une constante API.
Debug "WM_SIZING"
ResizeGadget(#EditorGadget, 10, 0, WindowWidth(#Window_Main) - 20, WindowHeight(#Window_Main) - 40) ; Modifie la taille du gadget.
FreeStatusBar(#StatusBar) ; Détruit la barre de status précédente et en recréé une.
MyStatusBar()
Default
EndSelect
StatusBarText(#StatusBar, 0, FormatDate("%dd/%mm/%yyyy", Date()) + " " + FormatDate("%hh:%ii:%ss", Date()))
StatusBarText(#StatusBar, 1, FileName + " " + Str(Len(GetGadgetText(#EditorGadget))) + " chars " + Str(NLines) + " lines " + Str(nchars)) ; Affiche le nom du ficher actuel et les statistiques.
Until Quit
SavePreferences(ProgramName + ".ini") ; Enregistres les valeurs des préférences.
EndIf
End