• Privacywetgeving
    Het is bij Helpmij.nl niet toegestaan om persoonsgegevens in een voorbeeld te plaatsen. Alle voorbeelden die persoonsgegevens bevatten zullen zonder opgaaf van reden verwijderd worden. In de vraag zal specifiek vermeld moeten worden dat het om fictieve namen gaat.

Klembord overvol - melding bij afsluiten

Status
Niet open voor verdere reacties.
Mogelijk dat ik het niet goed begrijp, maar de code DoEvents staat er al - weliswaar op een nieuwe regel.
Plaats ik DoEvents achter "Application.CommandBars("Office Clipboard").Visible = True" dan wordt de tekst rood (is dus fout)

Private Sub DoActionOfficeClipboard(ByVal AccObjName As String)
Dim Acc As Office.IAccessible
Dim Count As Long
Dim i As LongApplication.CommandBars("Office Clipboard").Visible = True

DoEvents
Set Acc = Application.CommandBars("Office Clipboard")
Set Acc = GetAcc(Acc, "x", ROLE_SYSTEM_PROPERTYPAGE)
 
Nu is het OK in een los testbestand (jouw versie) Raar maar waar :rolleyes:

Aanvulling:
Geplaatst in mijn volledig script werkt deze ook maar wel te runnen Na de routine Application.ScreenUpdating = True. Anders gaat het mis.
 
Laatst bewerkt:
Dus het aangepast bestand en code uit bericht#57 werken? (met "DoEvents").
"Application.ScreenUpdating = True" moet aan staan anders kan de code het venster niet openen.
Daarna simuleert de code de handelingen op het beeldscherm, om op een button te kunnen klikken (postmessage) moet die wel zichtbaar zijn.

Plaats anders je hele bestand, onbekende code in het bestand kan ook invloed hebben op de werking.
 
Laatst bewerkt:
Inderdaad met de aanpassing DoEvents draait bij mij de code zonder foutmeldingen e.d. Ook bevestig je mijn bevinding dat "Application.ScreenUpdating = True" aan moet staan voor het runnen van het script. Hieruit concludeer ik er geen andere code conflicteert.
Het hele bestand plaatsen kan ik helaas niet vanwege gevoelige inhoud. Wel zou ik de code van de relevante modules kunnen plaatsen mocht je daar interesse in hebben en dan liefst in een privé bericht.
Ik zal in een aparte reactie een samenvatting maken van deze topic.
 
Deze topic is m.i. in de afrondingsfase. Met heel veel dank aan degenen die hierin een zeer gewaardeerde bijdrage hebben geleverd !!:thumb: :thumb:
De stelling ergens op internet dat er geen code hiervoor bestaat is door de helpers van dit forum weerlegd !

Samenvatting.
Probleemstelling was de melding bij het afsluiten van een Excel bestand: "De afbeelding is te groot en zal worden afgekapt "
Oorzaak: Het Office klembord bevat te veel data om verder mee te kunnen werken. (uitkomst van het onderzoek)

Oplossingsvarianten:
1. Accepteer de melding - extra muisklik - geen invloed op de data in het bestand, er gaat niets mis.
2. Handmatig het klembord legen (lint) vóór het afsluiten
3. Wijzig kopieër/plak codes in codes die geen opslag in het klembord als gevolg hebben. zie #25
4. Voeg codes toe die het klembord legen na de laatste kopieër/plak routine (aan het einde van je laatste module) zie #38 en #57. Of er voor een van beide een voorkeur bestaat kan ik persoonlijk niet bepalen.
 
Verbeterde code, code in bericht#33 en bericht#37 hebben het nadeel dat je moet weten welke tekst op de button staat.
Deze code heeft dat nadeel niet.

Office klembord wissen, in alle resoluties en alle talen.
Clear office clipboard in all resolutions and all languages.

Code:
[SIZE=1]Option Explicit

Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hDC As Long, ByVal nIndex As Long) 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 EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Long, ByVal hDC As Long) As Long

Private Const LOGPIXELSX As Long = 88
Private Const LOGPIXELSY As Long = 90
Private Const WM_LBUTTONDOWN As Long = &H201&
Private Const WM_LBUTTONUP As Long = &H202&

Private Type tWindow
    Parent As Long
    Handle As Long
    Class As String
    Title As String
End Type

Private atWindow() As tWindow

Private miatWindow As Long

Private Function EnumChildProc(ByVal hwnd As Long, ByVal lParam As Long) As Long

    Dim lpClassName As String
    Dim lResult As Long

    miatWindow = miatWindow + 1

    ReDim Preserve atWindow(1 To miatWindow)

    lpClassName = Space(256)
    lResult = GetClassName(hwnd, lpClassName, 256)
    lpClassName = Left(lpClassName, lResult)

    With atWindow(miatWindow)
        .Handle = hwnd
        .Class = lpClassName
    End With

    EnumChildProc = 1

End Function


Public Sub ClearOfficeClipboardResolutionAndLanguageIndependent()    'alphamax_2016
'clears the office clipboard

    Dim bClipboard As Boolean
    Dim bScreenUpdating As Boolean
    Dim hDC As Long
    Dim hwnd As Long
    Dim iatWindow As Long
    Dim lDPIX As Long
    Dim lDPIY As Long
    Dim lParameter As Long

    With Application
        bClipboard = .CommandBars("Office Clipboard").Visible
        bScreenUpdating = .ScreenUpdating
        If Not bClipboard Then
            Application.CommandBars("Office Clipboard").Visible = True    'show office clipboard
        End If
        If Not bScreenUpdating Then
            .ScreenUpdating = True
        End If
    End With

    DoEvents

    hwnd = FindWindow("XLMAIN", Application.Caption)
    hwnd = FindWindowEx(hwnd, 0, "EXCEL2", "")

    EnumChildWindows hwnd, AddressOf EnumChildProc, ByVal 0&    'build windowdata tree

    For iatWindow = 1 To miatWindow
        If atWindow(iatWindow).Class = "bosa_sdm_XL9" Then    'get button
            hwnd = atWindow(iatWindow).Handle
        End If
    Next

    hDC = GetDC(0)
    lDPIX = GetDeviceCaps(hDC, LOGPIXELSX)
    lDPIY = GetDeviceCaps(hDC, LOGPIXELSY)
    ReleaseDC 0, hDC

    lParameter = 18 * lDPIY / 96 * 65536 + 120 * lDPIX / 96    'screen coords
    PostMessage hwnd, WM_LBUTTONDOWN, 0&, lParameter    'push button
    PostMessage hwnd, WM_LBUTTONUP, 0&, lParameter    'release button

    If Not bClipboard Then
        Application.CommandBars("Office Clipboard").Visible = False    'hide office clipboard
    End If
    If Not bScreenUpdating Then
        Application.ScreenUpdating = False
    End If

End Sub[/SIZE]
 

Bijlagen

  • helpmij anton44 clear office clipboard 2.xls
    50 KB · Weergaven: 63
Laatst bewerkt:
Blijkbaar heeft mijn vraag nogal wat losgeweekt :)
Bedankt voor deze optimalisatie.
Nu we er toch nog mee bezig zijn zou de code "Application.ScreenUpdating = True" aan het begin van je script toegevoegd kunnen worden om de kans op foutmeldingen te verminderen.

Groeten uit Ni-jwieërt.
 
Nieuwe code in bericht#67.
Groeten uit Wieërt-Zuid maar ook zeker de groeten aan de rest van de "harde"-kern van dit forum en het voormalige forum van worksheet.nl (je weet zelf wel of je jezelf daartoe mag rekenen).
 
Werkt prima. Bedankt.
Bij worksheet.nl heb ik ook vaker aangeklopt en bijgedragen, inderdaad.
 
Laatste (?) tip:
Zit de code in "This Workbook" als je automatisch wil legen zonder enig geflikker van je beeld.
Code:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ClearOfficeClipboardResolutionAndLanguageIndependent
End Sub
 
.
Groeten uit Wieërt-Zuid maar ook zeker de groeten aan de rest van de "harde"-kern van dit forum en het voormalige forum van worksheet.nl (je weet zelf wel of je jezelf daartoe mag rekenen).

Mooie taal-onafhankelijke oplossing alphamax!
en nog mooier als snb's Word-Tasks optie/suggestie aan de praat is te krijgen (de juiste parameters)
ennuh... groeten terug! :thumb:
 
@alpha

Om het maar eens op z'n TS te zeggen: 'het werkt niet'

Wat doe ik:

- ik open jouw bestand
- ik maak het office klembord zichtbaar
- ik verricht een aantal kopie-bewerkingen, die zichtbaar worden in het office klembord scherm.
- ik start de macro ClearOfficeClipboardResolutionAndLanguageIndependent
- ik tuur naar het Office klembordscherm
- en constateer dat daar niets is gewijzigd.

Wat gebruik ik:

- windows XP
- office 2010 (Engelstalige versie)

Zijn de API parameters voor diverse besturingssystemen verschillend ?
Of zit de crux in de coördinaten ( dus beeldschermafhankelijk) ?
 
Laatst bewerkt:
@snb.
Jammer..
Ik denk dat je toch iets verkeerd doet. Bij mij werkt het uitstekend.
Ik heb de hele code van alphamax in een aparte module geplaatst. Wel de code uit het bijbehorend voorbeeldbestand gebruiken.
 
getest op
windows7nl, excel2007nl, 96dpi->ok
windows7en, excel2013en, 96dpi->ok
windows8nl, excel2007nl, 144dpi->ok
windowsxp, excel2002, 96dpi->ok, na aanpassen code, Application.CommandBars werkt natuurlijk niet

Ik denk niet dat het aan de api's ligt dit zijn de bouwstenen van windows die moeten gelijk blijven vanwege compabiliteit.
Ook ligt het niet aan de verschillende resoluties, de code compenseert dat, of heb jij verschillende horizontale en verticale dpi?

Debug de code stap voor stap, in welke regels blijven de variabelen 0?

Je hebt toch niet "option explicit" verwijderd, gezien jij dat overbodig vindt. ;)

Edit: volgens deze link moet je Windows XP SP3 hebben, zie https://technet.microsoft.com/en-us/library/ee624351.aspx(v=office.14)#section7
 
Laatst bewerkt:
Dit zijn onze tussenstanden:

hwnd = FindWindow("XLMAIN", Application.Caption): 133432
FindWindowEx(hwnd, 0, "EXCEL2", ""): 133412

hwnd = atWindow(iatWindow).Handle: 68502

hDC = GetDC(0): -2013195667
hwnd = atWindow(iatWindow).Handle: 106
lDPIY = GetDeviceCaps(hDC, LOGPIXELSY): 106

lParameter = 18 * lDPIY / 96 * 65536 + 120 * lDPIX / 96: 1302660

PostMessage hwnd, WM_LBUTTONDOWN, 0&, lParameter: 68502,513,0&,1302660
PostMessage hwnd, WM_LBUTTONUP, 0&, lParameter: 68502,514,0&,1302660

Bij

clipboard.jpg
 
Laatst bewerkt:
handles zijn dynamisch dus dat is een beetje moeilijk vergelijken maar ik krijg wel een idee wat er gebeurt.
Code:
hwnd = atWindow(iatWindow).Handle: 106
kan volgens mij niet 106 is een dpi-waarde in jouw geval.
De regel hwnd = atWindow(iatWindow).Handle staat voor de regel lDPIY = GetDeviceCaps(hDC, LOGPIXELSY) dus hoe die 106 daar terecht komt is mij een raadsel.
 
Dat gong nog niet goed:

hwnd = FindWindow("XLMAIN", Application.Caption): 133504
FindWindowEx(hwnd, 0, "EXCEL2", ""): 133620

hwnd = atWindow(iatWindow).Handle: 68250

hDC = GetDC(0): 16842869
lDPIX = GetDeviceCaps(hDC, LOGPIXELSX: 106
lDPIY = GetDeviceCaps(hDC, LOGPIXELSY): 106
lParameter = 18 * lDPIY / 96 * 65536 + 120 * lDPIX / 96: 1302660

PostMessage hwnd, WM_LBUTTONDOWN, 0&, lParameter: 68250,513,0,1302660
PostMessage hwnd, WM_LBUTTONUP, 0&, lParameter: 68250,514,0,1302660
 
Laatst bewerkt:
De code middels de IAccessible nu sterk vereenvoudigd, volgens mij nu ook taalonafhankelijk

Omdat volgens mij de 'kinderen' van de office.iaccessible-objecten steeds op dezelfde locatie staan, deze keihard meegenomen in de code (1-3-0-3-2)
Ben benieuwd of dit daadwerkelijk zo is

Code:
Private Declare Function AccessibleChildren Lib "oleacc" (ByVal paccContainer As Office.IAccessible, ByVal iChildStart As Long, ByVal cChildren As Long, ByRef rgvarChildren As Any, ByRef pcObtained As Long) As Long

 Sub ClearOfficeClipBoard()
 Dim Acc As Office.IAccessible
   
   With Application
        .CommandBars("Office Clipboard").Visible = True
   DoEvents
        Set Acc = .CommandBars("Office Clipboard").accChild(1)
        Set Acc = zetAcc(Acc, 3)
        Set Acc = zetAcc(Acc, 0)
        Set Acc = zetAcc(Acc, 3)
        Acc.accDoDefaultAction 2&
        .CommandBars("Office Clipboard").Visible = False
   End With
   
 End Sub
 Private Function zetAcc(myAcc As Office.IAccessible, myChildIndex As Long) As Office.IAccessible
 Dim ReturnAcc As Office.IAccessible
 Dim Count As Long, List() As Variant
 
    Count = myAcc.accChildCount
    ReDim List(Count - 1&)
    If AccessibleChildren(myAcc, 0&, ByVal Count, List(0), Count) = 0& Then Set zetAcc = List(myChildIndex)
 
 End Function
 

Bijlagen

  • empty_office_Clipboard_EvR.xlsm
    16,8 KB · Weergaven: 67
Hi Eric,
Wat een vereenvoudiging en nog werkend ook nog !! :thumb: :thumb: :d

Heel erg bedankt.
Ton
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan