Bonjour,

CLASSEUR EXAMPLE

J'ai ecrit le code suivant pour designer un psudo-event (OnCellMouseMove) qui permet de detecter la cellule se trouvant sous le pointeur de la souris et par consequent pouvoir mettre en relief la cellule en utilisant les APIs de la librarie GDI.

j'aurrais pu tout simplement changer la couleur de la cellule ( Interior.Color proprieté) au lieu de dessiner directement su le Device Context mais cela fait perdre le Undo Stack .

Le code fonctionne bien sur excel 2007 et 2010 mais sur excel 2013 le highlight clignote brevement et puis disparait !

Y a t-il quelq'un qui puisse savoir quel est le problem avec excel 2013 et si le problem existe aussi en excel 2016 etc ...

Merci.



1- Code API dans un Standard Module:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
Option Explicit
 
Public Enum FRAME_STYLE
    FOCUSED_NO_COLOR = 0
    ETCHED_NO_COLOR = 1
    STRAIGHT = 2
    DASH = 3
    DOT = 4
End Enum
 
Private Type POINTAPI
    X As Long
    Y As Long
End Type
 
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 
Private Type BITMAP
    bmType As Long
    bmWidth As Long
    bmHeight As Long
    bmWidthBytes As Long
    bmPlanes As Integer
    bmBitsPixel As Integer
    #If  VBA7 Then
        bmBits As LongPtr
    #Else 
        bmBits As Long
    #End  If
End Type
 
Private Type BITMAPINFOHEADER '40 bytes
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
End Type
 
Private Type RGBQUAD
        rgbBlue As Byte
        rgbGreen As Byte
        rgbRed As Byte
        rgbReserved As Byte
End Type
 
Private Type BITMAPINFO
        bmiHeader As BITMAPINFOHEADER
        bmiColors As RGBQUAD
End Type
 
Private Type BLENDFUNCTION
    BlendOp As Byte
    BlendFlags As Byte
    SourceConstantAlpha As Byte
    AlphaFormat As Byte
End Type
 
Private Type LOGBRUSH
    lbStyle As Long
    lbColor As Long
#If  VBA7 Then
    lbHatch As LongPtr
#Else 
    lbHatch As Long
#End  If
End Type
 
Private Type LOGPEN
    lopnStyle As Long
    lopnWidth As POINTAPI
    lopnColor As Long
End Type
 
Private Type RGB
    R As Long
    G As Long
    B As Long
End Type
 
 
#If  VBA7 Then
 
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal hDC As LongPtr) As Long
    Private Declare PtrSafe Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As LongPtr, ByVal nWidth As Long, ByVal nHeight As Long) As LongPtr
    Private Declare PtrSafe Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As LongPtr) As LongPtr
    Private Declare PtrSafe Function DeleteDC Lib "gdi32" (ByVal hDC As LongPtr) As Long
    Private Declare PtrSafe Function DeleteObject Lib "gdi32" (ByVal hObject As LongPtr) As Long
    Private Declare PtrSafe Function SelectObject Lib "gdi32" (ByVal hDC As LongPtr, ByVal hObject As LongPtr) As LongPtr
    Private Declare PtrSafe Function FillRect Lib "user32" (ByVal hDC As LongPtr, lpRect As RECT, ByVal hBrush As LongPtr) As Long
    Private Declare PtrSafe Function DrawEdge Lib "user32" (ByVal hDC As LongPtr, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long
    Private Declare PtrSafe Function DrawFocusRect Lib "user32" (ByVal hDC As LongPtr, lpRect As RECT) As Long
    Private Declare PtrSafe Function SetRect Lib "user32" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Private Declare PtrSafe Function AlphaBlend Lib "msimg32.dll" (ByVal hDC As LongPtr, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal hDC As LongPtr, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal BLENDFUNCT As Long) As Long
    Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
    Private Declare PtrSafe Function RedrawWindow Lib "user32" (ByVal hwnd As LongPtr, lprcUpdate As RECT, ByVal hrgnUpdate As LongPtr, ByVal fuRedraw As Long) As Long
    Private Declare PtrSafe Function CreateBrushIndirect Lib "gdi32" (lpLogBrush As LOGBRUSH) As LongPtr
    Private Declare PtrSafe Function BitBlt Lib "gdi32" (ByVal hDestDC As LongPtr, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As LongPtr, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Private Declare PtrSafe Function TransparentBlt Lib "msimg32.dll" (ByVal hDC As LongPtr, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As LongPtr, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal crTransparent As Long) As Boolean
    Private Declare PtrSafe Function GetDIBits Lib "gdi32" (ByVal aHDC As LongPtr, ByVal hBitmap As LongPtr, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
    Private Declare PtrSafe Function SetDIBitsToDevice Lib "gdi32" (ByVal hDC As LongPtr, ByVal X As Long, ByVal Y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
    Private Declare PtrSafe Function LineTo Lib "gdi32" (ByVal hDC As LongPtr, ByVal X As Long, ByVal Y As Long) As Long
    Private Declare PtrSafe Function MoveToEx Lib "gdi32" (ByVal hDC As LongPtr, ByVal X As Long, ByVal Y As Long, lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function CreatePenIndirect Lib "gdi32" (lpLogPen As LOGPEN) As LongPtr
    Private Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hwnd As LongPtr, lpRect As RECT) As Long
    Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
    Private Declare PtrSafe Function GetClientRect Lib "user32" (ByVal hwnd As LongPtr, lpRect As RECT) As Long
    Private Declare PtrSafe Function ClientToScreen Lib "user32" (ByVal hwnd As LongPtr, lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function GetRgnBox Lib "gdi32" (ByVal hRgn As LongPtr, lpRect As RECT) As Long
    Private Declare PtrSafe Function CombineRgn Lib "gdi32" (ByVal hDestRgn As LongPtr, ByVal hSrcRgn1 As LongPtr, ByVal hSrcRgn2 As LongPtr, ByVal nCombineMode As Long) As Long
    Private Declare PtrSafe Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As LongPtr
    Private Declare PtrSafe Function RectInRegion Lib "gdi32" (ByVal hRgn As LongPtr, lpRect As RECT) As Long
    Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hwnd As LongPtr) As Long
 
#Else 
 
    Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare Function GetActiveWindow Lib "user32" () As Long
    Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
    Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
    Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long
    Private Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
    Private Declare Function SetRect Lib "user32" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal BLENDFUNCT As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function RedrawWindow Lib "user32" (ByVal hwnd As Long, lprcUpdate As RECT, ByVal hrgnUpdate As Long, ByVal fuRedraw As Long) As Long
    Private Declare Function CreateBrushIndirect Lib "gdi32" (lpLogBrush As LOGBRUSH) As Long
    Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Private Declare Function TransparentBlt Lib "msimg32.dll" (ByVal hdc As Long, ByVal X As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal crTransparent As Long) As Boolean
    Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
    Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
    Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal y As Long) As Long
    Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal y As Long, lpPoint As POINTAPI) As Long
    Private Declare Function CreatePenIndirect Lib "gdi32" (lpLogPen As LOGPEN) As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    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 GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
    Private Declare Function GetRgnBox Lib "gdi32" (ByVal hRgn As Long, lpRect As RECT) As Long
    Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
    Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Private Declare Function RectInRegion Lib "gdi32" (ByVal hRgn As Long, lpRect As RECT) As Long
    Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
 
#End  If
 
Private Const EDGE_ETCHED = &H6
Private Const BF_RECT = &HF
 
Private Const RDW_INVALIDATE = &H1
Private Const RDW_ALLCHILDREN = &H80
 
Private Const AC_SRC_OVER = &H0
Private Const SRCCOPY = &HCC0020
 
Private Const DIB_RGB_COLORS = 0&
Private Const BI_RGB = 0&
Private Const CAPTUREBLT = &H40000000
 
Private Const SIMPLEREGION = 2
Private Const COMPLEXREGION = 3
Private Const RGN_AND = 1
Private Const RGN_OR = 2
Private Const RGN_DIFF = 4
 
 
Public Sub HighlightCellUsingAlphaBlendMethod(ByVal Cell As Range, ByVal Color As Long)
    Call AlphaBlendRoutine(Cell, Color)
End Sub
 
 
Public Sub HighlightCellUsingDIBitsMethod(ByVal Cell As Range, ByVal Color As Long)
    Call DIBitsRoutine(Cell, Color)
End Sub
 
 
Public Sub DeHighlightCell(ByVal Cell As Range)
 
    Dim tCellRect As RECT
    tCellRect = ObjRect(Cell)
    With tCellRect
        Call SetRect(tCellRect, .Left - 1, .Top - 1, .Right + 1, .Bottom + 1)
    End With
    RedrawWindow 0, tCellRect, 0, RDW_INVALIDATE + RDW_ALLCHILDREN
    DoEvents
End Sub
 
 
Public Sub DrawFrame(ByVal Cell As Range, ByVal FrameStyle As FRAME_STYLE, ByVal FrameColor As Long)
 
    #If  VBA7 Then
        Dim hDC As LongPtr, hPen As LongPtr, hOldPen As LongPtr, hRgn As LongPtr, hCellRgn As LongPtr
    #Else 
        Dim hDC As Long, hPen As Long, hOldPen As Long, hRgn As Long, hCellRgn As Long
    #End  If
 
    Dim tRangeRect As RECT, tRealVisibleRect As RECT, tFrameRect   As RECT, tPen As LOGPEN, tpt As POINTAPI
    Dim lLeft As Long, lTop As Long, lRight As Long, lBottom As Long
    Dim RgnType As Long
 
    hDC = GetDC(0)
    tRangeRect = ObjRect(Cell)
    tRealVisibleRect = GetRealVisibleRangeRectPix
 
    With tRealVisibleRect
        hRgn = CreateRectRgn(.Left, .Top, .Right, .Bottom)
    End With
 
    With tRangeRect
        hCellRgn = CreateRectRgn(.Left, .Top, .Right, .Bottom)
    End With
 
    Call CombineRgn(hRgn, hRgn, hCellRgn, RGN_AND)
    Call GetRgnBox(hRgn, tFrameRect)
 
    With tFrameRect
        lLeft = .Left: lTop = .Top
        lRight = .Right:     lBottom = .Bottom
    End With
 
    Call ShapeOverlapsCell(tFrameRect, RgnType)
 
    If (tFrameRect.Left <> 0 And tFrameRect.Right <> 0) Then
        If FrameStyle = ETCHED_NO_COLOR Then
            Call DrawEdge(hDC, tFrameRect, EDGE_ETCHED, BF_RECT): GoTo Xit
        End If
        If FrameStyle = FOCUSED_NO_COLOR Then
            Call DrawFocusRect(hDC, tFrameRect): GoTo Xit
        End If
    Else
        GoTo Xit
    End If
 
    If RgnType = SIMPLEREGION Then
        With tFrameRect
            lLeft = .Left: lTop = .Top
            lRight = .Right:     lBottom = .Bottom
        End With
    End If
 
     With tPen
        .lopnColor = FrameColor
        .lopnStyle = FrameStyle - 2
        .lopnWidth.X = 1
        .lopnWidth.Y = 1
    End With
 
    hPen = CreatePenIndirect(tPen)
    hOldPen = SelectObject(hDC, hPen)
 
    Call MoveToEx(hDC, lLeft, lTop, tpt)
    Call LineTo(hDC, lRight, lTop)
 
    Call MoveToEx(hDC, lRight, lTop, tpt)
    Call LineTo(hDC, lRight, lBottom)
 
    Call MoveToEx(hDC, lRight, lBottom, tpt)
    Call LineTo(hDC, lLeft, lBottom)
 
    Call MoveToEx(hDC, lLeft, lBottom, tpt)
    Call LineTo(hDC, lLeft, lTop)
 
    Call SelectObject(hDC, hOldPen)
 
Xit:
    Call ReleaseDC(0, hDC)
    Call DeleteObject(hPen)
    Call DeleteObject(hOldPen)
    Call DeleteObject(hRgn)
    Call DeleteObject(hCellRgn)
 
End Sub
 
Public Sub GetCurPos(ByRef X As Long, ByRef Y As Long)
    Dim tpt As POINTAPI
    GetCursorPos tpt
    X = tpt.X: Y = tpt.Y
End Sub
 
 
 #If  VBA7 Then
    Public Function GetTheActiveWindow() As LongPtr
#Else 
    Public Function GetTheActiveWindow() As Long
 #End  If
        GetTheActiveWindow = GetActiveWindow
End Function
 
 
 
'**************************************************************************
'                                                       PRIVATE  ROUTINES
'**************************************************************************
 
 
Private Sub AlphaBlendRoutine(ByVal Cell As Range, ByVal Color As Long)
 
    #If  VBA7 Then
        Dim hDC As LongPtr, hMemDc As LongPtr, hMemBmp As LongPtr, hOldBmp As LongPtr, hCellRgn As LongPtr, hRgn As LongPtr, hBrush As LongPtr
    #Else 
        Dim hDC As Long, hMemDc As Long, hMemBmp As Long, hOldBmp As Long, hCellRgn As Long, hRgn As Long, hBrush As Long
    #End  If
 
    Dim tBF As BLENDFUNCTION, lBF As Long
    Dim tFill As LOGBRUSH, tRangeRect As RECT, tRealRect As RECT, tRgnRect As RECT
    Dim lLeft As Long, lTop As Long, lRight As Long, lBottom As Long, RgnType As Long
 
    tRangeRect = ObjRect(Cell)
    hDC = GetDC(0)
    hMemDc = CreateCompatibleDC(hDC)
    tRealRect = GetRealVisibleRangeRectPix
 
    With tRealRect
        hRgn = CreateRectRgn(.Left, .Top, .Right, .Bottom)
    End With
 
    With tRangeRect
        hCellRgn = CreateRectRgn(.Left, .Top, .Right, .Bottom)
    End With
 
    Call CombineRgn(hRgn, hRgn, hCellRgn, RGN_AND)
    Call GetRgnBox(hRgn, tRgnRect)
 
    With tRgnRect
        lLeft = .Left: lTop = .Top
        lRight = .Right:     lBottom = .Bottom
    End With
'
    Call ShapeOverlapsCell(tRgnRect, RgnType)
 
    With tRgnRect
        lLeft = .Left: lTop = .Top
        lRight = .Right:     lBottom = .Bottom
    End With
 
    hMemBmp = CreateCompatibleBitmap(hDC, lRight - lLeft, lBottom - lTop)
    hOldBmp = SelectObject(hMemDc, hMemBmp)
    Call SetRect(tRgnRect, 0, 0, lRight - lLeft, lBottom - lTop)
    tFill.lbColor = Color
    hBrush = CreateBrushIndirect(tFill)
    Call FillRect(hMemDc, tRgnRect, hBrush)
 
    With tBF
        .BlendOp = AC_SRC_OVER
        .BlendFlags = 0
        .SourceConstantAlpha = 50
        .AlphaFormat = 0
    End With
 
    Call CopyMemory(lBF, tBF, LenB(lBF))
    Call AlphaBlend(hDC, lLeft, lTop, lRight - lLeft, lBottom - lTop, hMemDc, 0, 0, lRight - lLeft, lBottom - lTop, lBF)
    Call SelectObject(hMemDc, hOldBmp)
 
    Call ReleaseDC(0, hDC)
    Call DeleteDC(hMemDc)
    Call DeleteObject(hMemBmp)
    Call DeleteObject(hBrush)
    Call DeleteObject(hOldBmp)
    Call DeleteObject(hCellRgn)
    Call DeleteObject(hRgn)
 
End Sub
 
 
Private Sub DIBitsRoutine(ByVal Cell As Range, ByVal Color As Long)
 
    #If  VBA7 Then
        Dim hDC As LongPtr, hMemDc As LongPtr, hMemBmp As LongPtr, hOldBmp As LongPtr, hCellRgn As LongPtr, hRgn As LongPtr
    #Else 
        Dim hDC As Long, hMemDc As Long, hMemBmp As Long, hOldBmp As Long, hCellRgn As Long, hRgn As Long
    #End  If
 
    Dim tRangeRect As RECT, tRealRect As RECT, tRgnRect   As RECT, tBMInfo As BITMAPINFO, tPixels() As RGBQUAD
    Dim X As Currency, Y As Currency, lCellColor As Long
    Dim lLeft As Long, lTop As Long, lRight As Long, lBottom As Long
 
    lCellColor = Cell.Interior.Color
    tRangeRect = ObjRect(Cell)
    hDC = GetDC(0)
    hMemDc = CreateCompatibleDC(hDC)
    tRealRect = GetRealVisibleRangeRectPix
 
    With tRealRect
        hRgn = CreateRectRgn(.Left, .Top, .Right, .Bottom)
    End With
 
    With tRangeRect
        hCellRgn = CreateRectRgn(.Left, .Top, .Right, .Bottom)
    End With
 
    Call CombineRgn(hRgn, hRgn, hCellRgn, RGN_AND)
    Call GetRgnBox(hRgn, tRgnRect)
 
    With tRgnRect
        lLeft = .Left: lTop = .Top
        lRight = .Right:     lBottom = .Bottom
    End With
 
        hMemBmp = CreateCompatibleBitmap(hDC, lRight - lLeft, lBottom - lTop)
        hOldBmp = SelectObject(hMemDc, hMemBmp)
        Call BitBlt(hMemDc, 0, 0, lRight - lLeft, lBottom - lTop, hDC, lLeft, lTop, SRCCOPY Or CAPTUREBLT)
        tBMInfo.bmiHeader.biSize = LenB(tBMInfo.bmiHeader)
        Call GetDIBits(hMemDc, hMemBmp, 0, 0, 0, tBMInfo, DIB_RGB_COLORS)
        ReDim tPixels(tBMInfo.bmiHeader.biWidth, tBMInfo.bmiHeader.biHeight)
        tBMInfo.bmiHeader.biCompression = BI_RGB
        Call GetDIBits(hMemDc, hMemBmp, 0, tBMInfo.bmiHeader.biHeight, tPixels(1, 1), tBMInfo, DIB_RGB_COLORS)
        Call SelectObject(hMemDc, hOldBmp)
 
        For X = 0 To tBMInfo.bmiHeader.biWidth
            For Y = 0 To tBMInfo.bmiHeader.biHeight
                If tPixels(X, Y).rgbRed = ColorToRGB(lCellColor).R And _
                tPixels(X, Y).rgbGreen = ColorToRGB(lCellColor).G And _
                tPixels(X, Y).rgbBlue = ColorToRGB(lCellColor).B Then
                    tPixels(X, Y).rgbRed = ColorToRGB(Color).R:  tPixels(X, Y).rgbGreen = ColorToRGB(Color).G:  tPixels(X, Y).rgbBlue = ColorToRGB(Color).B
                End If
            Next Y
        Next X
 
 
        Call SetDIBitsToDevice(hDC, lLeft, lTop, tBMInfo.bmiHeader.biWidth, tBMInfo.bmiHeader.biHeight, 0, 0, 0, tBMInfo.bmiHeader.biHeight, tPixels(1, 1), tBMInfo, DIB_RGB_COLORS)
 
    Call ReleaseDC(0, hDC)
    Call DeleteDC(hMemDc)
    Call DeleteObject(hMemBmp)
    Call DeleteObject(hOldBmp)
    Call DeleteObject(hCellRgn)
    Call DeleteObject(hRgn)
 
End Sub
 
 
Private Function ShapeOverlapsCell(ByRef HighlightRect As RECT, ByRef RGN_ERR As Long) As Boolean
 
    #If  VBA7 Then
        Dim hShapeRgn As LongPtr, hHighlightRgn As LongPtr, hDestRgn As LongPtr
    #Else 
        Dim hShapeRgn As Long, hHighlightRgn As Long, hDestRgn As Long
    #End  If
 
    Dim tTempRect As RECT, lCounter As Long
 
 
    For lCounter = 1 To ActiveSheet.Shapes.Count
        If ActiveSheet.Shapes(lCounter).FormControlType <> xlGroupBox Then
            tTempRect = ObjRect(ActiveSheet.Shapes(lCounter))
            If hDestRgn = 0 Then
                hDestRgn = CreateRectRgn(tTempRect.Left, tTempRect.Top, tTempRect.Right, tTempRect.Bottom)
            End If
            hShapeRgn = CreateRectRgn(tTempRect.Left, tTempRect.Top, tTempRect.Right, tTempRect.Bottom)
            Call CombineRgn(hDestRgn, hDestRgn, hShapeRgn, RGN_OR)
        End If
    Next lCounter
 
    If RectInRegion(hDestRgn, HighlightRect) Then
        hHighlightRgn = CreateRectRgn(HighlightRect.Left, HighlightRect.Top, HighlightRect.Right, HighlightRect.Bottom)
        RGN_ERR = CombineRgn(hHighlightRgn, hHighlightRgn, hDestRgn, RGN_DIFF)
        If RGN_ERR = COMPLEXREGION Then
            With HighlightRect
                .Left = 0:  .Top = 0:   .Right = 0:   .Bottom = 0
            End With
        Else
            GetRgnBox hHighlightRgn, HighlightRect
        End If
        ShapeOverlapsCell = True
    End If
 
    DeleteObject hHighlightRgn
    DeleteObject hShapeRgn
    DeleteObject hDestRgn
 
End Function
 
 
Private Function GetRealVisibleRangeRectPix() As RECT
 
    #If  VBA7 Then
        Static hWbk As LongPtr
        Dim hDesk As LongPtr, hVert As LongPtr, hHoriz As LongPtr
    #Else 
        Static hWbk As Long
        Dim hDesk As Long, hVert As Long, hHoriz As Long
    #End  If
 
    Dim tDeskRect As RECT, WrkbookRect As RECT, VerRect As RECT, HorizRect As RECT, tPt1 As POINTAPI, tpt2 As POINTAPI
 
 
    hDesk = FindWindowEx(Application.hwnd, 0, "XLDESK", vbNullString)
    Call GetWindowRect(hDesk, tDeskRect)
    If hWbk = 0 Then hWbk = GetThisWorkbookHwnd
 
    Call GetClientRect(hWbk, WrkbookRect)
    tPt1.X = WrkbookRect.Left: tPt1.Y = WrkbookRect.Top
    tpt2.X = WrkbookRect.Right: tpt2.Y = WrkbookRect.Bottom
    Call ClientToScreen(hWbk, tPt1)
    Call ClientToScreen(hWbk, tpt2)
    WrkbookRect.Left = tPt1.X: WrkbookRect.Top = tPt1.Y
    WrkbookRect.Right = tpt2.X: WrkbookRect.Bottom = tpt2.Y
     hVert = FindWindowEx(hWbk, 0, "NUIScrollbar", "Vertical")
     hHoriz = FindWindowEx(hWbk, 0, "NUIScrollbar", "Horizontal")
    If IsWindowVisible(hHoriz) Or ThisWorkbook.Windows(1).DisplayWorkbookTabs Then
        Call GetWindowRect(hHoriz, HorizRect)
    End If
    If IsWindowVisible(hVert) Then
        Call GetWindowRect(hVert, VerRect)
    End If
 
    With Application.ActiveWindow
        GetRealVisibleRangeRectPix.Left = Application.Max(.ActivePane.PointsToScreenPixelsX(.VisibleRange.Cells(1, 1).Left) + (.Zoom / 100), tDeskRect.Left)
        GetRealVisibleRangeRectPix.Top = Application.Max(.ActivePane.PointsToScreenPixelsY(.VisibleRange.Cells(1, 1).Top) + (.Zoom / 100), tDeskRect.Top)
        GetRealVisibleRangeRectPix.Right = Application.Min(WrkbookRect.Right - (VerRect.Right - VerRect.Left), tDeskRect.Right)
        GetRealVisibleRangeRectPix.Bottom = Application.Min(WrkbookRect.Bottom - (HorizRect.Bottom - HorizRect.Top), tDeskRect.Bottom)
    End With
 
End Function
 
 
#If  VBA7 Then
    Private Function GetThisWorkbookHwnd() As LongPtr
#Else 
    Private Function GetThisWorkbookHwnd() As Long
#End  If
 
    Dim sCaption As String
 
    On Error GoTo Xit
    sCaption = ThisWorkbook.Windows(1).Caption
    ThisWorkbook.Windows(1).Caption = "@@{}@@"
    GetThisWorkbookHwnd = FindWindowEx(FindWindowEx(Application.hwnd, 0, "XLDESK", vbNullString), 0, "EXCEL7", "@@{}@@")
Xit:
    ThisWorkbook.Windows(1).Caption = sCaption
 
End Function
 
 
Private Function ColorToRGB(ByVal Col As Long) As RGB
    ColorToRGB.R = &HFF& And Col
    ColorToRGB.G = (&HFF00& And Col) \ 256
    ColorToRGB.B = (&HFF0000 And Col) \ 65536
End Function
 
 
Private Function ObjRect(ByVal Obj As Object) As RECT
 
    Dim oPane  As Pane
    Set oPane = ThisWorkbook.Windows(1).ActivePane
 
    With Obj
        ObjRect.Left = oPane.PointsToScreenPixelsX(.Left - 1)
        ObjRect.Top = oPane.PointsToScreenPixelsY(.Top - 1)
        ObjRect.Right = oPane.PointsToScreenPixelsX(.Left + .Width)
        ObjRect.Bottom = oPane.PointsToScreenPixelsY(.Top + .Height)
    End With
 
End Function
 
 
 
'I chose not to use this Approach because the 'TransparentBlt' API causes memory leaks.
'======================================================================
'Private Sub TransparentBltRoutine(ByVal Cell As Range, ByVal Color As Long)
'
'    #If  VBA7 Then
'        Dim hdc As LongPtr, hMemDc As LongPtr, hMemBmp As LongPtr, hMemDc2 As LongPtr, hMemBmp2 As LongPtr, hBrush As LongPtr, hOldBmp As LongPtr, hOldBmp2 As LongPtr
'    #Else 
'        Dim hdc As Long, hMemDc As Long, hMemBmp As Long, hMemDc2 As Long, hMemBmp2 As Long, hBrush As Long, hOldBmp As Long, hOldBmp2 As Long
'    #End  If
'
'    Dim tRangeRect As RECT, tRealRect As RECT, tMemRect As RECT, tMemRect2 As RECT, tFill As LOGBRUSH
'    Dim lLeft As Long, lTop As Long, lRight As Long, lBottom As Long, lCellColor As Long
'
'    lCellColor = Cell.Interior.Color
'    tRangeRect = ObjRect(Cell)
'    hdc = GetDC(0)
'
'    With tRangeRect
'        hMemDc = CreateCompatibleDC(hdc)
'        hMemBmp = CreateCompatibleBitmap(hdc, .Right - .Left, .Bottom - .Top)
'        hOldBmp = SelectObject(hMemDc, hMemBmp)
'        hMemDc2 = CreateCompatibleDC(hdc)
'        hMemBmp2 = CreateCompatibleBitmap(hdc, .Right - .Left, .Bottom - .Top)
'        hOldBmp2 = SelectObject(hMemDc2, hMemBmp2)
'        Call SetRect(tMemRect, 0, 0, .Right - .Left, .Bottom - .Top)
'        Call SetRect(tMemRect2, 0, 0, .Right - .Left, .Bottom - .Top)
'        tFill.lbColor = Color
'        hBrush = CreateBrushIndirect(tFill)
'        Call FillRect(hMemDc2, tMemRect2, hBrush)
'        Call BitBlt(hMemDc, 0, 0, .Right - .Left, .Bottom - .Top, hdc, .Left, .Top, SRCCOPY)
'        Call TransparentBlt(hMemDc2, 0, 0, .Right - .Left, .Bottom - .Top, hMemDc, 0, 0, .Right - .Left, .Bottom - .Top, lCellColor)
'        Call SelectObject(hMemDc, hOldBmp)
'        tRealRect = GetRealVisibleRangeRectPix
'        lLeft = Application.Min(.Left, tRealRect.Right): lTop = Application.Min(.Top, tRealRect.Bottom)
'        lRight = Application.Min(.Right, tRealRect.Right): lBottom = Application.Min(.Bottom, tRealRect.Bottom)
'    End With
'
'    BitBlt hdc, lLeft, lTop, lRight - lLeft, lBottom - lTop, hMemDc2, 0, 0, SRCCOPY
'    Call SelectObject(hMemDc2, hOldBmp2)
'
'    Call ReleaseDC(0, hdc)
'    Call DeleteDC(hMemDc)
'    Call DeleteDC(hMemDc2)
'    Call DeleteObject(hMemBmp)
'    Call DeleteObject(hMemBmp2)
'    Call DeleteObject(hOldBmp)
'    Call DeleteObject(hOldBmp2)
'    Call DeleteObject(hBrush)
'
'End Sub

2- Code de Classe Module: (HighlightClass)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
Option Explicit
 
Private WithEvents Cmbrs As CommandBars
Private WithEvents Wbevents As Workbook
 
 
Public Sub Start()
    Set Cmbrs = Application.CommandBars
    Set Wbevents = ThisWorkbook
    Call Cmbrs_OnUpdate
End Sub
 
Public Sub Finish()
    Call ThisWorkbook.OnCellMouseMove(Nothing)
    Set Cmbrs = Nothing
    Set Wbevents = Nothing
End Sub
 
 
Private Sub wbevents_Activate()
    Call Me.Start
End Sub
 
Private Sub Wbevents_Deactivate()
    Call Me.Finish
End Sub
 
Private Sub Wbevents_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    Call Me.Start
End Sub
 
 
Private Sub Cmbrs_OnUpdate()
 
    Static oPrevCell As Range
    Dim oCurCell  As Range
    Dim X As Long, Y As Long
 
    On Error Resume Next
 
    Application.CommandBars.FindControl(ID:=2040).Enabled = Not Application.CommandBars.FindControl(ID:=2040).Enabled
 
    If GetTheActiveWindow <> Application.hwnd Then
        Exit Sub
    End If
 
    GetCurPos X, Y
    Set oCurCell = ActiveWindow.RangeFromPoint(X, Y)
 
    If TypeName(oCurCell) = "Range" Then
        If oPrevCell.Address <> oCurCell.Address Then
            Set oPrevCell = oCurCell
            Call ThisWorkbook.OnCellMouseMove(oCurCell)
        End If
    Else
        Call DeHighlightCell(oPrevCell)
    End If
 
End Sub

3- Code dans le ThisWorkbook Module:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Option Explicit
 
Private oHighlightInstance As HighlightClass
 
Public Sub StartMacro()
    If oHighlightInstance Is Nothing Then
        Set oHighlightInstance = New HighlightClass
        oHighlightInstance.Start
    End If
End Sub
 
 
Public Sub StopMacro()
    If Not oHighlightInstance Is Nothing Then
        oHighlightInstance.Finish
        Set oHighlightInstance = Nothing
    End If
End Sub
 
 
 
'**********************************************************
'                 PSEUDO-EVENT
'**********************************************************
 
Public Sub OnCellMouseMove(ByVal CellUnderMousePointer As Range)
 
    Static oPrevCell As Range
    Dim lDrawMethod As Long
    Dim lFrame As Long
 
 
    lDrawMethod = 1 ' set to 2 for AlphaBlending or 0 for NoDrawing.
    lFrame = 1 ' set to 0 for NoFrame.
 
    If oPrevCell Is Nothing Then Set oPrevCell = ActiveCell
    If CellUnderMousePointer Is Nothing Then Call DeHighlightCell(oPrevCell): Exit Sub
 
    'Apply to Sheet1 only - comment out this line to apply to all sheets.
    If CellUnderMousePointer.Parent.Name <> "Sheet1" Then Exit Sub
 
    If Not CellUnderMousePointer Is Nothing Then
        Call DeHighlightCell(oPrevCell)
        Set oPrevCell = CellUnderMousePointer
        If lDrawMethod = 1 Then
            Call HighlightCellUsingDIBitsMethod(CellUnderMousePointer, vbYellow)
        ElseIf lDrawMethod = 2 Then
            Call HighlightCellUsingAlphaBlendMethod(CellUnderMousePointer, vbYellow)
        End If
        If lFrame = 1 Then
            Call DrawFrame(CellUnderMousePointer, DOT, vbRed)
        End If
    End If
 
End Sub