Code plakken op forums

Het Firefox venster activeren

In deel 1 van dit artikel hebben we reeds gezien hoe we alle code uit een module kunnen kopiëren en in het Windows Klembord plaatsen, aangevuld met vaste tekst. In deel 2 van het artikel buigen we ons over de vraag hoe we automatisch het venster van Firefox actief kunnen maken. Mozilla Firefox is mijn favoriete internet browser waarmee ik Excel VBA forums bezoek. De 2 meest gebruikte methoden om een ander venster actief te maken, zijn:

  1. de SendKeys methode van het Application object
  2. de AppActivate methode

Application.SendKeys bootst een toetsencombinatie na die je zelf opgeeft. Als je manueel Alt + Tab zou drukken om een ander venster te activeren, kan je die Alt + Tab ook door VBA laten uitvoeren:

Application.SendKeys "%{TAB}"

Alt + Tab kan echter niet naar een willekeurig venster springen, hiervoor moet je in het algemeen meerdere keren Alt + Tab achter elkaar uitvoeren. Deze methode is aldus te beperkt om echt nuttig te zijn; onze code moet zelf op zoek gaan naar het venster van Firefox, waar het zich ook bevindt.

Laten we eerst naar AppActivate kijken. Die methode vraagt 1 parameter: de tekst van het Venster die je bovenaan in de balk ziet staan. Voor een Internet Explorer venster zou dit kunnen zijn: "Google - Windows Internet Explorer". Voor Word zou dit kunnen zijn: "Telefoonlijst.docx - Microsoft Word". Voor een topic op MrExcel via Firefox zou dit kunnen zijn: "Macro to Hide Columns - MrExcel Message Board - Mozilla Firefox". Zoals je ziet, kan hier vanalles staan: dat is de keuze van de maker van de website / de applicatie. Surf ik op MrExcel.com naar een andere topic, dan verandert dit weer. Met andere woorden, je hebt geen vaste tekst, dus met enkel AppActivate gaan we er niet geraken: AppActivate werkt enkel als je de volledige en exacte tekst van het venster kent.

Hoe dan wél? We zouden één voor één alle vensters kunnen afgaan, en kijken of de WindowText het woord "Firefox" bevat. Hier ga je te maken krijgen met Windows API calls: dat zijn algemene functies die niet zozeer met Excel en VBA te maken hebben (kan wel) maar eerder over de hele PC van de gebruiker: wat zijn de instellingen van het beeldscherm, hoe kan je de CDROM-lader aansturen, enz. Zo ook, informatie omtrent de vensters die actief zijn op een bepaald moment.

Na het nodige zoekwerk blijkt dat er een drietal interessante Windows API calls bestaan voor het zoeken van het juiste venster:

  • FindWindowEx
  • GetWindowText
  • GetClassName

FindWindowEx laat toe om met bepaalde startwaarden een handle naar een actief Venster op te vragen. Een handle is een nummer (een variabele gedeclareerd als Long) waaronder dat venster gekend is in Windows op het moment van opvragen. Dat is een uniek nummer: aan de hand van dat nummer kan je andere informatie opvragen over dat venster, bvb. de tekst bovenaan in de balk. Dat kan je doen met GetWindowText, een functie die als parameters o.a. die handle zal hebben.

Elk venster heeft ook een ClassName, die vindt je met behulp van GetClassName. Die naam is niet uniek. Voor een actief venster van Firefox blijkt de ClassName "MozillaUIWindowClass" te zijn.

Alles komt samen

Nu hebben we alle tools ter beschikking: we kunnen een lus maken doorheen alle vensters, en krijgen daarvoor telkens een handle (uniek nummer naar het geheugen). Op basis van dit nummer vragen we zowel de ClassName als de WindowText op, en kijken of dit lijkt op die voor Firefox. Indien ja, dan stoppen we de zoekactie; indien neen, dan zoeken we verder.

' Wim Gielis ' http://www.wimgielis.com
''''' ' VBA-code to copy VBA-code in a module to the Clipboard and activate a Firefox window ' 14/11/09 '''''
Option Compare Text 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 GetClassName Lib "user32" _ Alias "GetClassNameA" (ByVal hWnd As Long, _ ByVal lpClassName As String, _ ByVal nMaxCount As Long) As Long Private Declare Function GetWindowText Lib "user32" _ Alias "GetWindowTextA" (ByVal hWnd As Long, _ ByVal lpString As String, _ ByVal cch As Long) As Long
Sub CopyCodeToForum()
Dim DataObj As New MSForms.DataObject With ActiveWorkbook.VBProject.VBComponents("Module1").CodeModule DataObj.SetText "Hi there," & vbCr & vbCr & "Consider:" & vbCr & "[code]" & _ .Lines(1, .CountOfLines) & "[/code]" & vbCr & vbCr & "Wigi" DataObj.PutInClipboard End With s = fWindowText("MrExcel Message Board - Mozilla Firefox", "MozillaWindowClass") If Len(s) Then AppActivate s Application.Wait Now + TimeValue("00:00:01") / 100 Application.SendKeys "+{INSERT}", True End If
End Sub
Function fWindowText(sWindowText As String, Optional sClass As String) As String
Dim hWnd As Long, lRet As Long, sText As String hWnd = FindWindowEx(0, 0, vbNullString, vbNullString) Do While hWnd <> 0 'ClassName sText = String(100, Chr(0)) lRet = GetClassName(hWnd, sText, 100) If Len(sClass) = 0 Or Left(sText, lRet) = sClass Then 'WindowText sText = String(100, Chr(0)) lRet = GetWindowText(hWnd, sText, 100) If InStr(sText, sWindowText) Then fWindowText = Left(sText, lRet) Exit Function End If End If hWnd = FindWindowEx(0, hWnd, vbNullString, vbNullString) Loop
End Function

Wordt toch nog vervolgd…

Zo, dit is de hele code, en nu weten jullie waarom ik soms zo snel code op een forum zet ;-)

Over Wim

Wim Gielis is Business Intelligence consultant en Excel expert

Andere links