[VB] Text "plakken" in het active window

Pagina: 1
Acties:

  • PolarBear
  • Registratie: Februari 2001
  • Niet online
Ik ben bezig de functionaliteit van PureText (http://stevemiller.net/puretext/) na te maken. Dit is aardig gelukt, alleen een functie lukt niet helemaal. Deze functie is namelijk het direct plakken van text in een active window, eigenlijk hetzelfde wat ctrl-c doet.

Wat doet het programma:
Je kopieert een stukje text van bv een webpagina
Je doet ctrl-d (of een andere toetsencombinatie waar op het programma reageert) en de text wordt in plain text in het active window gepasted. (Omdat WinXP nogal de neiging heeft om het als RTF te plakken enzo).

Ik heb deze code (irrelevante zaken even weggelaten)

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Declare Function SendMessageSTRING Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long

Private Declare Function GetForegroundWindow Lib "user32" () As Long

Dim sTemp As String
Dim lCurHwnd As Long
Dim lEdit As Long

sTemp = Clipboard.GetText(vbCFText)
lCurHwnd = GetForegroundWindow
lEdit = FindWindowEx(lCurHwnd, 0&, "Edit", vbNullString)
SendMessageSTRING lEdit, WM_SETTEXT, 256, stemp


Dit werk ook, maar alleen in Notepad. In MDI programma's raakt hij de kluts kwijt lijkt het wel.

Het probleem lijkt te zitten in:
Visual Basic:
1
lEdit = FindWindowEx(lCurHwnd, 0&, "Edit", vbNullString)

De 0& zou, als ik het goed begrepen heb de handle van de cild window moeten zijn. Ik kan echter niets relevants op het internet vinden.


Iemand een suggestie :?

  • Tukk
  • Registratie: Januari 2002
  • Laatst online: 13-05 11:42

Tukk

De α-man met het ẞ-brein

Mischien heb je wat aan de help op MSDN?

http://msdn.microsoft.com...unctions/FindWindowEx.asp

Het zit hem in die tweede parameter volgens mij. Als je daar 1 van de handles van
een child window mee geeft gaat hij daarna zelf op zoek naar een
ander "broertje"-window dat voldoet aan je zoektocht.

Correct me if i am wrong, het is en blijft zondagochtend.

Q: How many geeks does it take to ruin a joke? A: You mean nerd, not geek. And not joke, but riddle. Proceed.


  • PolarBear
  • Registratie: Februari 2001
  • Niet online
Dat heb ik inderdaad ook gevonden, maar hoe weet ik nu of het de active window is ?

Als ik hier kijk http://msdn.microsoft.com...unctions/FindWindowEx.asp dan zou je denken dat GetForegroundWindow sowieso de active window handle retourneert.

/edit 2

Is het misschien mogelijk om (even een uber ranzige methode) crtl-c te simuleren, netzoals send keys ? (bij mijn weten werkt send keys alleen binnen de applicatie)

[ Voor 83% gewijzigd door PolarBear op 27-07-2003 11:57 . Reden: Extra info ]


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 09:58

alienfruit

the alien you never expected

Kun je niet gewoon een WM_KEYDOWN of WM_PASTE message sturen naar dat venster? Ik denk nu hard op hoor, dus bind me er niet aan vast :)

  • PolarBear
  • Registratie: Februari 2001
  • Niet online
Grr... WM_PASTE geeft hetzelfde probleem...

[ Voor 141% gewijzigd door PolarBear op 27-07-2003 13:43 ]


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 09:58

alienfruit

the alien you never expected

Ik volg het niet meer :)
Het is een programma waarbij je eerst iets kopieert van WinApp1 en later ga je naar een WinApp2 en druk je op Ctrl+D en plak je de tekst in het actieve venster van WinApp2 ofzo?

Als je dit wil dan kun je wel WM_PASTE gebruiken alleen dan moet je dus het actieve window weten *en* het active (edit) control om dit venster omdat niet elke window in Windows een WM_PASTE kan opvangen of gebruiken.

Misschien zoiets?


Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// send Paste command to a active window!
function SendPasteToActiveWnd( aTarget: THandle ) : Boolean;
var hActiveWnd, hFocusWnd: THandle;
      KeyStroke: Word;
      oldKS, newKS: TKeyboardState;
const
      HIT_CONTROL = $81;
begin
    result := false;
    if ( IsWindow( aTarget ) == false ) then Exit;
 
    aThread   := GetWindowThreadProcessId( aTarget, nil );
    if AttachThreadInput( GetCurrentThreadId(), aThread, true) then
    begin
          //
          //
          hFocusWnd := GetFocus;
          if ( hFocusWnd <> 0 ) then   // ADDED 14:57
          begin
               KeyStroke := VkKeyScan( 'v' );  // get keystroke back
               GetKeyboardSate( oldKS );       // get current keyboard state (capslock etc.)
               GetKeyboardSate( newKS );       // get current keyboard state
               newKS[ VK_CONTROL ]         := HIT_CONTROL;
               SetKeyboardState( newKS );
               //
               PostMessage( aTarget, WM_KEYDOWN, KeyStroke, 1 );
               PostMessage( aTarget, WM_KEYUP, KeyStroke, 1 ); 
               //
               SetKeyboardState( oldKS );
          end;               
         AttachThreadInput( GetCurrentThreadId(), aThread , False );
         Result := true;
     end else
    begin
         ShowMessage( 'Attaching to the thread failed.' );
    end;
end;


Wat doet het?
Als eerste hangt het de input processing mechanisme aan het actieve venster, vervolgens vraagt het de Keystroke van V op. Vervolgens vraagt het de status van de keyboard op, nadat het deze status heeft ontvangen veranderd het deze zodat je ook de Control-key ingedrukt hebt. Nadat deze verandering is doorgevoerd veranderd het tijdelijk de keyboard status om vervolgens als eerst een KeyDown message (je hebt de V toets ingedrukt) in te drukken en vervolgens stuur je de KeyUp message (je laat de V toets weer los) want je moet deze ALTIJD samen sturen bij zulke dingen. Vervolgens zet het de oude keyboard status weer terug.

Alleen probleem het is code dat ik een hele tijd heb gevonden, en het is geschreven in Delphi en niet VB (gebruik ik niet meer).

[ Voor 198% gewijzigd door alienfruit op 27-07-2003 15:03 ]


  • PolarBear
  • Registratie: Februari 2001
  • Niet online
alienfruit schreef op 27 July 2003 @ 14:21:
Ik volg het niet meer :)
Het is een programma waarbij je eerst iets kopieert van WinApp1 en later ga je naar een WinApp2 en druk je op Ctrl+D en plak je de tekst in het actieve venster van WinApp2 ofzo?

Als je dit wil dan kun je wel WM_PASTE gebruiken alleen dan moet je dus het actieve window weten *en* het active (edit) control om dit venster omdat niet elke window in Windows een WM_PASTE kan opvangen of gebruiken.
Sorry was een beetje geiriteerd om dat Visual Basic een beetje aan het bokken was.. stomme IDE crashte ...

Inderdaad het "probleem" is niet zozeer de active window, maar het active (of althans editeble) control.

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 09:58

alienfruit

the alien you never expected

Oh, dan moet je gewoon alle child windows van je actieve windows doorlopen en de style parameters bekijken of het een EDIT control is. :)

Je zou bijv al wel een lijst kunnen maken met de doro jouw bekende classnames die dit zijn. ;) Als je een onbekende classname tegen bent gekomen moet je kijken of je kunt zien of het een EDIT CONTROL is (dan moet je dus een [sub]class EDIT, RICHEDIT hebben) de editor style ES_MULTILINE gaaf aan dat het een multiline edit control is (dus een memo).

Via de GetWindowLong-functi ekun je dat doen:
Checken of een control een Multiline edit control is:

Delphi:
1
2
3
4
5
6
7
8
9
const
   ES_MULTILINE = 4;      // multi line control
   ES_READONLY  = $800;      // read only control


if GetWindowLong( aHandle,  GWL_STYLE ) and ES_MULTILINE and not ES_READONLY ) then
begin
     // code hier
end;


Note: Trouwens met me code hierboven kun je ook gebruiken om GetFocus aan te roepen, dan krijg je het active control van je actieve window terug :)


Ik hoop dat je er toch nog wat aan hebt afgezien dat het Delphi code is!

[ Voor 102% gewijzigd door alienfruit op 27-07-2003 15:13 ]


  • PolarBear
  • Registratie: Februari 2001
  • Niet online
_/-\o_ Hoewel het Delphi is ga ik het toch eens proberen.

* PolarBear heeft nog nooit wat met API's gedaan

[ Voor 72% gewijzigd door PolarBear op 27-07-2003 15:29 ]


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 09:58

alienfruit

the alien you never expected

Ooh. Ik ook niet verschrikbarend veel maar wel wat :) Alleen de API's die nodig hebt om een leuke component te schrijven in Delphi :)
Pagina: 1