[Resolu] Ecrire dans une fenêtre externe...

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
gildev
Messages : 380
Inscription : mar. 19/juin/2007 10:28
Localisation : Picardie (France)

[Resolu] Ecrire dans une fenêtre externe...

Message par gildev »

J'ai bien avancé dans mon programme, du coup je m'intéresse à des fonctions moins importantes mais qui peuvent être agréables. Par exemple, je souhaite écrire des pixels dans une fenêtre externe, du style tracer un rectangle, une ligne, un point...

Voici une illustration de ce que j'aimerai réaliser sur la fenêtre B:
Image

Est-ce possible ou simple fantasme?
Dernière modification par gildev le dim. 24/août/2008 14:30, modifié 1 fois.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Bonjour Gildev

J'ai ces codes de NETMAESTRO qui pourront peut etre t'aider

Code : Tout sélectionner

;========================================================================== 
; Program:          Add a functional button to the Windows Calculator 
; Author:           netmaestro 
; Date:             June 11, 2007 
; Target Compiler:  PureBasic 4.0 and later 
; Target OS:        Microsoft Windows XP Only 
;========================================================================== 

Global oldproc, quit=0, cebutton, clearbutton, one, two, three 
Global four, five, six, seven, eight, nine, zero, point 

Procedure ButtonProc(hwnd, msg, wParam, lParam) 
  Select msg 
    Case #WM_NCDESTROY 
      End 
    Case #WM_LBUTTONUP 
      SendMessage_(cebutton, #BM_CLICK, 0,0) 
      SendMessage_(three,    #BM_CLICK, 0,0) 
      SendMessage_(point,    #BM_CLICK, 0,0) 
      SendMessage_(one,      #BM_CLICK, 0,0) 
      SendMessage_(four,     #BM_CLICK, 0,0) 
      SendMessage_(one,      #BM_CLICK, 0,0) 
      SendMessage_(five,     #BM_CLICK, 0,0) 
  EndSelect 
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wParam, lParam) 
EndProcedure 

Procedure GetClearButtons(hwnd, param) 
  wt.s = Space(10) 
  SendMessage_(hwnd, #WM_GETTEXT, 10, @wt) 
  If wt = "C" 
    clearbutton = hwnd 
  ElseIf wt = "CE" 
    cebutton = hwnd 
  EndIf 
  ProcedureReturn 1 
EndProcedure 

Procedure GetNumbers(hwnd, param) 
  wt.s = Space(10) 
  SendMessage_(hwnd, #WM_GETTEXT, 10, @wt) 
  Select wt 
    Case "1" : one = hwnd 
    Case "2" : two = hwnd 
    Case "3" : three = hwnd 
    Case "4" : four = hwnd 
    Case "5" : five = hwnd 
    Case "6" : six = hwnd 
    Case "7" : seven = hwnd 
    Case "8" : eight = hwnd 
    Case "9" : nine = hwnd 
    Case "0" : zero = hwnd 
    Case "." : point = hwnd 
    EndSelect 
    ProcedureReturn 1 
EndProcedure 

RunProgram("calc.exe") 
start = ElapsedMilliseconds() 
Repeat 
  c = FindWindow_(0, "Calculatrice") 
  Delay(1) 
Until c Or ElapsedMilliseconds()-start > 500 

If c 
  EnumChildWindows_(c, @GetClearButtons(), 0) 
  EnumChildWindows_(c, @GetNumbers(), 0) 
  SetWindowPos_(clearbutton, 0,0,0,28,29,#SWP_NOZORDER|#SWP_NOMOVE|#SWP_FRAMECHANGED) 
  InitCommonControls_() 
  GetWindowRect_(c, @cr.RECT) 
  w = cr\right-cr\left 
  If w > 270 ; Scientific 
    button = CreateWindowEx_(0,"Button", "PI", #WS_CHILD|#WS_VISIBLE,432,62,28,29,c,0,GetModuleHandle_(0),0) 
  Else ; Standard 
    button = CreateWindowEx_(0,"Button", "PI", #WS_CHILD|#WS_VISIBLE,216,37,28,29,c,0,GetModuleHandle_(0),0) 
  EndIf 
Else 
  MessageRequester("OOPS!", "Can't find the Calculator!", #MB_ICONERROR) 
  End 
EndIf 

oldproc = SetWindowLong_(button, #GWL_WNDPROC, @ButtonProc()) 

result = GetMessage_(@msg.MSG, #Null, #Null, #Null) 
While result <> 0 
  If result = -1 ; GetMessage failed 
    MessageRequester("OOPS!", "Failure in GetMessage Loop", #MB_ICONERROR) 
    End 
  EndIf 
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
  result = GetMessage_(@msg.MSG, #Null, #Null, #Null) 
Wend 

Code : Tout sélectionner

;========================================================================== 
; Program:          Add a functional button to the Windows Calculator 
; Author:           netmaestro 
;========================================================================== 

Global oldproc, quit=0, cebutton, clearbutton, one, two, three 
Global four, five, six, seven, eight, nine, zero, point 

Procedure ButtonProc(hwnd, msg, wParam, lParam) 
  Select msg 
    Case #WM_NCDESTROY 
      End 
    Case #WM_LBUTTONUP 
      SendMessage_(cebutton, #BM_CLICK, 0,0) 
      SendMessage_(three,    #BM_CLICK, 0,0) 
      SendMessage_(point,    #BM_CLICK, 0,0) 
      SendMessage_(one,      #BM_CLICK, 0,0) 
      SendMessage_(four,     #BM_CLICK, 0,0) 
      SendMessage_(one,      #BM_CLICK, 0,0) 
      SendMessage_(five,     #BM_CLICK, 0,0) 
  EndSelect 
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wParam, lParam) 
EndProcedure 

Procedure GetClearButtons(hwnd, param) 
  CtrlID = GetDlgCtrlID_(hwnd) 
  
  If CtrlID = 81 
    clearbutton = hwnd 
  ElseIf CtrlID = 82 
    cebutton = hwnd 
  EndIf 
  ProcedureReturn 1 
EndProcedure 

Procedure GetNumbers(hwnd, param) 
  Select GetDlgCtrlID_(hwnd) 
    Case 124 : zero = hwnd 
    Case 125 : one = hwnd 
    Case 126 : two = hwnd 
    Case 127 : three = hwnd 
    Case 128 : four = hwnd 
    Case 129 : five = hwnd 
    Case 130 : six = hwnd 
    Case 131 : seven = hwnd 
    Case 132 : eight = hwnd 
    Case 133 : nine = hwnd 
    Case 85 : point = hwnd 
    EndSelect 
    ProcedureReturn 1 
EndProcedure 


CalcProgramID = RunProgram("Calc.Exe", "", "", #PB_Program_Open) 

If CalcProgramID 
  CalcProcessID = ProgramID(CalcProgramID) 
  Count = 0 
  Repeat 
    Delay(100)          ; Avoid hanging of windows during start of application while searching for the window 
    Count = Count + 1   ; Security counter to avoid hanging 
    WinHandle = FindWindow_(0,0) 
    While WinHandle <> 0 
      GetWindowThreadProcessId_(WinHandle, @ProcessID) 
      If ProcessID = CalcProcessID 
        c = WinHandle 
        Break 
      EndIf 
      WinHandle = GetWindow_(WinHandle, #GW_HWNDNEXT) 
    Wend 
  Until c Or (Count=50) ; Wait up to 5 seconds for window to occur 
EndIf 

If c 
  EnumChildWindows_(c, @GetClearButtons(), 0) 
  EnumChildWindows_(c, @GetNumbers(), 0) 
  SetWindowPos_(clearbutton, 0,0,0,28,29,#SWP_NOZORDER|#SWP_NOMOVE|#SWP_FRAMECHANGED) 
  InitCommonControls_() 
  GetWindowRect_(c, @cr.RECT) 
  w = cr\right-cr\left 
  If w > 270 ; Scientific 
    button = CreateWindowEx_(0,"Button", "PI", #WS_CHILD|#WS_VISIBLE,432,62,28,29,c,0,GetModuleHandle_(0),0) 
  Else ; Standard 
    button = CreateWindowEx_(0,"Button", "PI", #WS_CHILD|#WS_VISIBLE,216,37,28,29,c,0,GetModuleHandle_(0),0) 
  EndIf 
Else 
  MessageRequester("OOPS!", "Can't find the Calculator!", #MB_ICONERROR) 
  End 
EndIf 

oldproc = SetWindowLong_(button, #GWL_WNDPROC, @ButtonProc()) 

result = GetMessage_(@msg.MSG, #Null, #Null, #Null) 
While result <> 0 
  If result = -1 ; GetMessage failed 
    MessageRequester("OOPS!", "Failure in GetMessage Loop", #MB_ICONERROR) 
    End 
  EndIf 
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
  result = GetMessage_(@msg.MSG, #Null, #Null, #Null) 
Wend 
Et celui-ci de NETMAESRO et SHARDIK
http://www.purebasic.fr/english/viewtopic.php?t=27548

Code : Tout sélectionner

Global oldproc, quit=0, cebutton, clearbutton, one, two, three 
Global four, five, six, seven, eight, nine, zero, point 

Procedure ButtonProc(hwnd, msg, wParam, lParam) 
  Select msg 
    Case #WM_NCDESTROY 
      End 
    Case #WM_LBUTTONUP 
      SendMessage_(cebutton, #BM_CLICK, 0,0) 
      SendMessage_(three,    #BM_CLICK, 0,0) 
      SendMessage_(point,    #BM_CLICK, 0,0) 
      SendMessage_(one,      #BM_CLICK, 0,0) 
      SendMessage_(four,     #BM_CLICK, 0,0) 
      SendMessage_(one,      #BM_CLICK, 0,0) 
      SendMessage_(five,     #BM_CLICK, 0,0) 
  EndSelect 
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wParam, lParam) 
EndProcedure 

Procedure GetClearButtons(hwnd, param) 
  CtrlID = GetDlgCtrlID_(hwnd) 
  
  If CtrlID = 81 
    clearbutton = hwnd 
  ElseIf CtrlID = 82 
    cebutton = hwnd 
  EndIf 
  ProcedureReturn 1 
EndProcedure 

Procedure GetNumbers(hwnd, param) 
  Select GetDlgCtrlID_(hwnd) 
    Case 124 : zero = hwnd 
    Case 125 : one = hwnd 
    Case 126 : two = hwnd 
    Case 127 : three = hwnd 
    Case 128 : four = hwnd 
    Case 129 : five = hwnd 
    Case 130 : six = hwnd 
    Case 131 : seven = hwnd 
    Case 132 : eight = hwnd 
    Case 133 : nine = hwnd 
    Case 85 : point = hwnd 
    EndSelect 
    ProcedureReturn 1 
EndProcedure 


CalcProgramID = RunProgram("Calc.Exe", "", "", #PB_Program_Open) 

If CalcProgramID 
  CalcProcessID = ProgramID(CalcProgramID) 
  Count = 0 
  Repeat 
    Delay(100)          ; Avoid hanging of windows during start of application while searching for the window 
    Count = Count + 1   ; Security counter to avoid hanging 
    WinHandle = FindWindow_(0,0) 
    While WinHandle <> 0 
      GetWindowThreadProcessId_(WinHandle, @ProcessID) 
      If ProcessID = CalcProcessID 
        c = WinHandle 
        Break 
      EndIf 
      WinHandle = GetWindow_(WinHandle, #GW_HWNDNEXT) 
    Wend 
  Until c Or (Count=50) ; Wait up to 5 seconds for window to occur 
EndIf 

If c 
  EnumChildWindows_(c, @GetClearButtons(), 0) 
  EnumChildWindows_(c, @GetNumbers(), 0) 
  SetWindowPos_(clearbutton, 0,0,0,28,29,#SWP_NOZORDER|#SWP_NOMOVE|#SWP_FRAMECHANGED) 
  InitCommonControls_() 
  GetWindowRect_(c, @cr.RECT) 
  w = cr\right-cr\left 
  If w < 270 ; Standard 
    If OSVersion() = #PB_OS_Windows_NT_4 
      yPosPIButton = 46 
    Else 
      yPosPIButton = 37 
    EndIf      
    button = CreateWindowEx_(0,"Button", "PI", #WS_CHILD|#WS_VISIBLE,216,yPosPIButton,28,29,c,0,GetModuleHandle_(0),0) 
  EndIf 
  RedrawWindow_(button, 0, 0, #RDW_UPDATENOW) 
Else 
  MessageRequester("OOPS!", "Can't find the Calculator!", #MB_ICONERROR) 
  End 
EndIf 

oldproc = SetWindowLong_(button, #GWL_WNDPROC, @ButtonProc()) 

result = GetMessage_(@msg.MSG, #Null, #Null, #Null) 
While result <> 0 
  If result = -1 ; GetMessage failed 
    MessageRequester("OOPS!", "Failure in GetMessage Loop", #MB_ICONERROR) 
    End 
  EndIf 
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
  result = GetMessage_(@msg.MSG, #Null, #Null, #Null) 
Wend 
Bonne soirée
Dernière modification par Kwai chang caine le ven. 22/août/2008 22:41, modifié 2 fois.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Salut, enchanté,

ça doit être possible.

Je vois deux méthodes :

1) La tricherie : une fenêtre sans rebord qui fait office d'image du rectangle, et si tu veux des motifs plus complexes, voire en dégradé, il y a différentes méthodes dans le sujet lancé par Dobro. Tu fais alors carrément une fenêtre semi-transparente qui recouvre intégralement ta fenêtre externes.

2) La « high-tech » que je ne connais pas, faute de parcourir les fonctions API. LSI, je pense, en serait capable. NetMaestro, sur le forum anglais. Chris aussi peut-être. En gros, elle consiste à retrouver la liste de gadgets de ta fenêtre externe et à y insérer un nouveau gadget image. Pour ma part, je ne sais même pas moi-même modifier la liste de gadgets d'une fenêtre PB sans utiliser une méthode grossière (effacer la liste et la refaire)
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

@Kwaï t'as cartonné !!! Tu m'as soufflé la place !!
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Pour une fois :D

Il est trop fort ce NETMAESTRO 8)
Avatar de l’utilisateur
gildev
Messages : 380
Inscription : mar. 19/juin/2007 10:28
Localisation : Picardie (France)

Message par gildev »

Je viens de tester le 1er code, c'est à tomber par terre. J'ignorais qu'on pouvais aller jusque là. A première vue je pense que je vais trouver ce que je cherche en l'épluchant. Je vous tiens au courant.

Merci à tous les deux! :wink:
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

je comprends a peut pres comment il ajoute un bouton "PI" a la calculatrice windows , mais par contre, je ne comprends pas comment il arrive a lui faire afficher le chiffre PI (3.1415926536) 8O

j'ai beau regarder le code, je ne vois aucune allusion a la fonction PI 8O :?

et pourtant .... ça marche ! :)
Avatar de l’utilisateur
gildev
Messages : 380
Inscription : mar. 19/juin/2007 10:28
Localisation : Picardie (France)

Message par gildev »

En fait il simule l'appuie des boutons de la calculatrice, du moins je pense...

Code : Tout sélectionner

SendMessage_(cebutton, #BM_CLICK, 0,0)
SendMessage_(three,    #BM_CLICK, 0,0)
SendMessage_(point,    #BM_CLICK, 0,0)
SendMessage_(one,      #BM_CLICK, 0,0)
SendMessage_(four,     #BM_CLICK, 0,0)
SendMessage_(one,      #BM_CLICK, 0,0)
SendMessage_(five,     #BM_CLICK, 0,0)
En tout cas c'est puissant, très puissant.
Avatar de l’utilisateur
gildev
Messages : 380
Inscription : mar. 19/juin/2007 10:28
Localisation : Picardie (France)

Message par gildev »

J'ai un peu trituré le source, c'est fort intéressant et ça peut être utile un jour. Mais maleureusement ça ne résoud pas mon problème.

Il faut juste en fait que je trouve comment faire un Plot(x, y [, Couleur]) sur une appli externe. Ce qui n'est pas tout à faire pareil. Je prie pour que l'un de vous possède ça dans ses archives... :cry:

En attendant je continue mes recherches sur MSDN.

PS: Au passage j'ai laissé un post sur le forum anglais au cas où...
djmcg
Messages : 139
Inscription : sam. 28/août/2004 6:37

Message par djmcg »

Bonjour,

Pardon d'intervenir sans donner de solution.
Quelle belle fenêtre !!!
je suppose que ce n'est pas sous linux que l'on peut faire cela.

Excusé moi encore.

Jean-Marie :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops:
Dernière modification par djmcg le sam. 23/août/2008 8:20, modifié 1 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

gildev a écrit :En fait il simule l'appuie des boutons de la calculatrice, du moins je pense...

Code : Tout sélectionner

SendMessage_(cebutton, #BM_CLICK, 0,0)
SendMessage_(three,    #BM_CLICK, 0,0)
SendMessage_(point,    #BM_CLICK, 0,0)
SendMessage_(one,      #BM_CLICK, 0,0)
SendMessage_(four,     #BM_CLICK, 0,0)
SendMessage_(one,      #BM_CLICK, 0,0)
SendMessage_(five,     #BM_CLICK, 0,0)
En tout cas c'est puissant, très puissant.
ha bah oui !! quel âne fais-je :lol:
Avatar de l’utilisateur
gildev
Messages : 380
Inscription : mar. 19/juin/2007 10:28
Localisation : Picardie (France)

Message par gildev »

Bon. Pas de bol. Personne n'a l'air de savoir sur le forum anglais.
Quant à MSDN je n'ai pas tout épluché, donc il y a encore un espoir...
Dernière modification par gildev le dim. 24/août/2008 11:57, modifié 1 fois.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Fais une recherche sur AttachProcess.
Avatar de l’utilisateur
gildev
Messages : 380
Inscription : mar. 19/juin/2007 10:28
Localisation : Picardie (France)

Message par gildev »

Bon, les recherches sur AttachProcess n'ont rien donné qui peuvent m'aider. Merci quand même de m'avoir répondu. :cry:

Par contre cette nuit j'ai eu pas mal de messages sur le forum anglais, avec des débuts de solutions à étudier. :D Vu que le célebre netmaestro
s'intéresse à mon problème je pense que ça peut donner un résulat. :lol:

Je vous tiens au courant.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

C'est pas une question facile, parce qu'il s'agit d'attaquer un programme sur lequel normalement tu n'as aucun droit. J'ai déjà fait un truc qui me permettait d'agir sur un programme tierce (il s'agissait simplement de le forcer à se mettre à l'arrière plan), en utilisant attachprocess, un peu comme ici http://www.purebasic.fr/english/viewtop ... achprocess mais en moins compliqué. A priori, une fois que tu as lié ton process à l'autre, tu peux faire ce que tu veux, donc récupérer son DC, etc.
Mais ce n'est pas évident, si possible il vaudrait mieux une autre solution. Dans le lien fourni, ils disent que pour que l'attachprocess soit vraiment valide, il faut le mettre dans une DLL; j'avoue que moi à l'époque je ne m'étais pas embêté avec ça et que ça fonctionnait très bien!
Répondre