Basic Univers
; Code de : Nico
; But     : Retrouver le mot contenu dans un éditeur sous le curseur de la souris

; Explications :
;   Ce code est très pratique et peut servir à afficher une aide contextuelle
;       ou un ToolTip pour aider l'utilisateur sur des mots clés par exemple.
;   Le message #EM_CHARFROMPOS est l'inverse de #EM_POSFROMCHAR, c'est le point de départ du code.
;   L'utilisation du message #EM_CHARFROMPOS varie suivant la version de
;       RichEdit comme pour #EM_POSFROMCHAR, donc voir MSDN!



Global editeur

Procedure Editeur(Window.l, Message, Wparam, lparam)
  Editeur_Origin = GetProp_(Window, "Editeur_Origin")
  Select Message
    Case #WM_MOUSEMOVE
          ; Ce message nous donne les coordonnées du curseur relatives à l'éditeur
          point.point\x = lparam & $ffff
          point\y = lparam>>16
         
          ; On récupère l'index du caractere se trouvant sous le curseur
          index_caractere = SendMessage_(editeur, #EM_CHARFROMPOS , 0, @point.point)
         
          ; Maintenant on récupère l'index de la ligne
          index_line = SendMessage_(editeur, #EM_LINEFROMCHAR, index_caractere, 0)
         
          ; On récupère aussi l'index du premier caractère de la ligne
          First_caratere_in_line = SendMessage_(editeur, #EM_LINEINDEX, index_line, 0)
         
          ; ce qui permet ensuite de déterminer la position du caractere dans la ligne
          Pos_caractere_in_line = index_caractere - First_caratere_in_line
   
          ; Ces lignes de code récupèrent le texte de la ligne
          ; j'aurais pu utiliser la commande de Pure: GetGadgetItemText
          tampon.s = Space(65000)
          PokeW(@tampon, 64999)
          SendMessage_(editeur, #EM_GETLINE, index_line, @tampon)
         
          ; J'ajuste la longueur de la chaine
          pos = FindString(tampon, Chr(13), 1)
          tampon = PeekS(@tampon, pos - 1)

          ; Cette partie du code sert à déterminer le mot se trouvant sous le curseur
          SetGadgetText(10, "")
         
          If pos - 1<>Pos_caractere_in_line
              pos1 = FindString(tampon, " ", Pos_caractere_in_line + 1)
              If pos1 <>Pos_caractere_in_line + 1
                   If pos1
                      tampon = PeekS(@tampon, pos1 - 1)
                   EndIf
                 
                   *pointeur =@tampon + Len(tampon)- 1
                   While *pointeur>=@tampon
                      If PeekS(*pointeur, 1)=" "
                          Break
                      EndIf
                      *pointeur =*pointeur - 1
                   Wend
                   Longueur =  @tampon + Len(tampon)-*pointeur - 1
                   mot.s = PeekS(*pointeur + 1, Longueur)

                   Debut = First_caratere_in_line + Len(tampon)- Longueur
                   Fin = First_caratere_in_line + Len(tampon)
                   SendMessage_(Window, #EM_SETSEL, Debut, Fin)
                   
                   SetGadgetText(10, mot)
              EndIf
          Else
              SendMessage_(Window, #EM_SETSEL, 1, 1)
          EndIf


          Case #WM_NCPAINT
              result = CallWindowProc_(Editeur_Origin, Window, Message, Wparam, lparam)
              Hdc = GetDC_(Window)
              hpen = CreatePen_(#PS_SOLID, 1, RGB(255, 255, 255))
              If Window = editeur
                  SelectObject_(hdc, hpen)
                  MoveToEx_(hdc, - 1, - 1, #Null)
                  LineTo_(hdc, 290 - 2, - 1)
                  LineTo_(hdc, 290 - 2, 180 - 2)
                  LineTo_(hdc, - 1, 180 - 2)
                  SelectObject_(hdc, hpen2)
                  LineTo_(hdc, - 1, - 1)
              EndIf
              DeleteObject_(hpen)
              ReleaseDC_(Window, Hdc)
              ProcedureReturn result
  EndSelect
             
  ProcedureReturn CallWindowProc_(Editeur_Origin, Window, Message, Wparam, lparam)
EndProcedure



Procedure.l Editeur_Init(Window.l)
    Editeur_Origin = GetProp_(Window, "Editeur_Origin")
    If Editeur_Origin = 0
        Editeur_Origin = SetWindowLong_(Window, #GWL_WNDPROC, @Editeur())
        SetProp_(Window, "Editeur_Origin", Editeur_Origin)
    EndIf
EndProcedure




If OpenWindow(0, 0, 0, 400, 300, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))

    hbruh1 = CreateSolidBrush_(RGB(255, 255, 0))
    SetClassLong_(WindowID(0), #GCL_HBRBACKGROUND, hbruh1)
    InvalidateRect_(window0, 0, 1)
    StringGadget(10, 40, 10, 100, 20, "")
   
    Hcontainer = ContainerGadget(0, 40, 40, 318, 208, 0)


    hbruh2 = CreateSolidBrush_(RGB(0, 0, 255))

    SetClassLong_(Hcontainer, #GCL_HBRBACKGROUND, hbruh2)
    InvalidateRect_(Hcontainer, 0, 1)
   
   
    editeur = EditorGadget(1, 14, 14, 290, 180)
    SetWindowLong_(editeur, #GWL_STYLE, GetWindowLong_(editeur, #GWL_STYLE)|#WS_BORDER)
    SetWindowLong_(editeur, #GWL_EXSTYLE, GetWindowLong_(editeur, #GWL_EXSTYLE)!#WS_EX_CLIENTEDGE)

    Editeur_Init(editeur)

    SetWindowPos_(editeur, #Null, #Null, #Null, #Null, #Null, #SWP_NOMOVE|#SWP_NOSIZE|#SWP_NOZORDER|#SWP_NOACTIVATE|#SWP_FRAMECHANGED)
    RedrawWindow_(editeur, #Null, #Null, #RDW_INVALIDATE|#RDW_NOCHILDREN|#RDW_UPDATENOW|#RDW_FRAME)

    chaine.s = "Balader le curseur de la souris" + Chr(13)+"sur cette phrase sans cliquer" + Chr(13)+"Et voyer le texte sous le curseur s'afficher dans le StringGadget."
    AddGadgetItem(1, a, chaine)

  Repeat
    event = WaitWindowEvent()
 
  Until event = #PB_Event_CloseWindow
  DeleteObject_(hbruh1)
  DeleteObject_(hbruh2)
EndIf