Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «О Ρ‡Ρ‘ΠΌ Π½Π΅ ΠΏΠΈΡˆΡƒΡ‚ Π² ΠΊΠ½ΠΈΠ³Π°Ρ… ΠΏΠΎ DelphiΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 38

Автор А. Π“Ρ€ΠΈΠ³ΠΎΡ€ΡŒΠ΅Π²

1.3.3.2. Π Π΅Π³ΠΈΠΎΠ½Ρ‹

Π Π΅Π³ΠΈΠΎΠ½Ρ‹ β€” это особыС графичСскиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ собой области ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΡ‹. ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ Π½Π° Ρ„ΠΎΡ€ΠΌΡƒ Ρ€Π΅Π³ΠΈΠΎΠ½Π° Π½Π΅Ρ‚, ΠΎΠ½ΠΈ Π΄Π°ΠΆΠ΅ Π½Π΅ обязаны Π±Ρ‹Ρ‚ΡŒ связными. БущСствуСт ряд Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для создания Ρ€Π΅Π³ΠΈΠΎΠ½ΠΎΠ² простых Ρ„ΠΎΡ€ΠΌ (CreateRectRgn, CreateEllipticRgn, CreatePolygonRgn ΠΈ Ρ‚.ΠΏ.), Π° Ρ‚Π°ΠΊΠΆΠ΅ функция Π‘ombineRgn для объСдинСния Ρ€Π΅Π³ΠΈΠΎΠ½ΠΎΠ² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ способами. ВсС это вмСстС позволяСт ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Ρ€Π΅Π³ΠΈΠΎΠ½Ρ‹ Π»ΡŽΠ±Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌ. ΠžΠ±Π»Π°ΡΡ‚ΡŒ примСнСния Ρ€Π΅Π³ΠΈΠΎΠ½ΠΎΠ² достаточно ΡˆΠΈΡ€ΠΎΠΊΠ°. Π Π°Π½Π΅Π΅ ΠΌΡ‹ ΡƒΠΆΠ΅ Π²ΠΈΠ΄Π΅Π»ΠΈ, ΠΊΠ°ΠΊ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ€Π΅Π³ΠΈΠΎΠ½ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ Π²Ρ‹Π²ΠΎΠ΄Π° Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ. Π—Π΄Π΅ΡΡŒ ΠΆΠ΅ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ SetWindowRgn ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΡƒ ΠΎΠΊΠ½Π°, придавая Π΅ΠΌΡƒ Ρ„ΠΎΡ€ΠΌΡƒ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ€Π΅Π³ΠΈΠΎΠ½Π°.

1.3.3.3. БообщСния WM_SIZE ΠΈ WM_SIZING

Бобытия WM_SIZE ΠΈ WM_SIZING ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΎΠΊΠ½Ρƒ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Π΅Π³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ. Π’ "классичСском" Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Ρ‚ΡΠ½ΡƒΡ‚ΡŒ Ρ€Π°ΠΌΠΊΡƒ ΠΎΠΊΠ½Π°, Π½Π° экранС рисуСтся "Ρ€Π΅Π·ΠΈΠ½ΠΎΠ²Ρ‹ΠΉ" ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ сторона ΠΈΠ»ΠΈ ΡƒΠ³ΠΎΠ» ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ двиТСтся Π·Π° курсором ΠΌΡ‹ΡˆΠΈ. Окно ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ сообщСниС WM_SIZING ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° этого ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ°. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ lParam ΠΏΡ€ΠΈ этом содСрТит ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру TRect с Π½ΠΎΠ²Ρ‹ΠΌΠΈ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°ΠΌΠΈ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ°. Окно ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ эти ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹, Π½ΠΎ ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈΡ…, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π² Ρ‚Π΅ΠΌ самым Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ измСнСния Ρ€Π°Π·ΠΌΠ΅Ρ€Π°. На этом, Π² частности, основано использованиС свойства Constraints: Ссли Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΎΠΊΠ½Π° ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ становится мСньшС ΠΈΠ»ΠΈ большС Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ, ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ сообщСния WM_SIZING Ρ€Π°Π·ΠΌΠ΅Ρ€ увСличиваСтся ΠΈΠ»ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ Π΄ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ wParam содСрТит ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΎΠΌ, Π·Π° ΠΊΠ°ΠΊΡƒΡŽ сторону ΠΈΠ»ΠΈ ΡƒΠ³ΠΎΠ» тянСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π·Π½Π°Π»Π°, ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΈΠ· ΡƒΠ³Π»ΠΎΠ² ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ° Π½ΡƒΠΆΠ½ΠΎ ΡΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ, Ссли Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ такая Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ.

ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΡ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΎΠΊΠ½Π° ΠΈ отпустит ΠΊΠ½ΠΎΠΏΠΊΡƒ ΠΌΡ‹ΡˆΠΈ, ΠΎΠΊΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ сообщСниС WM_SIZE. ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ этого сообщСния ΠΎΠΊΠ½ΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ сСбя с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ Π½ΠΎΠ²Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ². (Окно ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ сообщСниС WM_SIZE послС измСнСния Π΅Π³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΏΠΎ любой ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅, Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ·-Π·Π° дСйствий ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.)

ΠžΠΏΠΈΡΠ°Π½Π½Ρ‹ΠΉ "классичСский" Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π² чистом Π²ΠΈΠ΄Π΅ сущСствуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Windows 95. Π’ΠΎ всСх Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ·Π΄Π½ΠΈΡ… вСрсиях ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π° опция отобраТСния содСрТимого ΠΎΠΊΠ½Π° ΠΏΡ€ΠΈ пСрСтаскивании ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² (начиная с Windows Π₯Π  эта опция Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π½ΠΎ ΠΈ Π½Π΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ срСдствами ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ интСрфСйса). Π’ Ρ‚Π°ΠΊΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΎΠΊΠ½Π° вмСсто ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ° "Ρ€Π΅Π·ΠΈΠ½ΠΎΠ²Ρ‹ΠΌ" становится само ΠΎΠΊΠ½ΠΎ, ΠΈ любоС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΡ‹ΡˆΠΈ ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ пСрСрисовкС ΠΎΠΊΠ½Π°. Π’ этом Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΎΠΊΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ сообщСниС WM_SIZE ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· послС сообщСния WM_SIZING, Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ измСнСния Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ². Но Π² Ρ†Π΅Π»ΠΎΠΌ Π»ΠΎΠ³ΠΈΠΊΠ° этих сообщСний остаСтся ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΉ, просто с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ это выглядит Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ измСняСт Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΎΠΊΠ½Π° "ΠΏΠΎ Ρ‡ΡƒΡ‚ΡŒ-Ρ‡ΡƒΡ‚ΡŒ".

1.3.3.4. А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ β€” всС вмСстС

ΠšΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΡ описанных достаточно простых Π²Π΅Ρ‰Π΅ΠΉ позволяСт ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΎΠΊΠ½ΠΎ с Π΄Ρ‹Ρ€ΠΊΠΎΠΉ, ΠΈΠΌΠ΅ΡŽΡ‰Π΅ΠΉ измСняСмыС Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹.

Для Π½Π°Ρ‡Π°Π»Π° объявим нСсколько констант, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°ΠΌ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ вычислСнии Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² Π΄Ρ‹Ρ€ΠΊΠΈ ΠΈ Ρ‚.ΠΏ. (листинг 1.51).

Листинг 1.51. ΠšΠΎΠ½ΡΡ‚Π°Π½Ρ‚Ρ‹ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° WndHole

const

 // минимальноС расстояниС ΠΎΡ‚ Π΄Ρ‹Ρ€ΠΊΠΈ Π΄ΠΎ края ΠΎΠΊΠ½Π°

 HoleDistance = 40;

 // Π—ΠΎΠ½Π° Ρ‡ΡƒΠ²ΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Ρ€Π°ΠΌΠΊΠΈ ΠΏΠ°Π½Π΅Π»ΠΈ - Π½Π° сколько пиксСлов

 // ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΡΡ‚ΠΎΡΡ‚ΡŒ курсор Π²Π³Π»ΡƒΠ±ΡŒ ΠΎΡ‚ края ΠΏΠ°Π½Π΅Π»ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΅Π³ΠΎ

 // ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ€Π°ΡΡ†Π΅Π½ΠΈΠ²Π°Π»ΠΎΡΡŒ ΠΊΠ°ΠΊ ΠΏΠΎΠΏΠ°Π΄Π°Π½ΠΈΠ΅ Π² Ρ€Π°ΠΌΠΊΡƒ.

 BorderMouseSensivity = 3;

 // Π—ΠΎΠ½Π° Ρ‡ΡƒΠ²ΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΡƒΠ³Π»Π° Ρ€Π°ΠΌΠΊΠΈ ΠΏΠ°Π½Π΅Π»ΠΈ - Π½Π° сколько пиксСлов

 // ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΡΡ‚ΠΎΡΡ‚ΡŒ курсор ΠΎΡ‚ ΡƒΠ³Π»Π° ΠΏΠ°Π½Π΅Π»ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΅Π³ΠΎ

 // ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ€Π°ΡΡ†Π΅Π½ΠΈΠ²Π°Π»ΠΎΡΡŒ ΠΊΠ°ΠΊ ΠΏΠΎΠΏΠ°Π΄Π°Π½ΠΈΠ΅ Π² ΡƒΠ³ΠΎΠ» Ρ€Π°ΠΌΠΊΠΈ.

 CornerMouseSensivity = 15;

 // Π’ΠΎΠ»Ρ‰ΠΈΠ½Π° Ρ€Π°ΠΌΠΊΠΈ Π΄Ρ‹Ρ€ΠΊΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°ΡΡΡ ΠΏΡ€ΠΈ вычислСнии Ρ€Π΅Π³ΠΈΠΎΠ½Π°

 HoleBorder = 3;

 // Минимальная ΡˆΠΈΡ€ΠΈΠ½Π° ΠΈ высота Π΄Ρ‹Ρ€ΠΊΠΈ

 MinHoleSize = 10;

 // Π‘ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ стрСлки ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΡƒΠ³Π»Π°

 ArrowOffset = 8;

Π’Π΅ΠΏΠ΅Ρ€ΡŒ приступаСм ΠΊ созданию ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. На Ρ„ΠΎΡ€ΠΌΡƒ "ΠΊΠ»Π°Π΄Π΅ΠΌ" панСль. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ SetWindowRgn устанавливаСм Ρ‚Π°ΠΊΡƒΡŽ Ρ„ΠΎΡ€ΠΌΡƒ ΠΎΠΊΠ½Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ ΠΏΠ°Π½Π΅Π»ΠΈ Π±Ρ‹Π»Π° Π²ΠΈΠ΄Π½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°ΠΌΠΊΠ°, Π° Π½Π° всю Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΡŽΡŽ Ρ‡Π°ΡΡ‚ΡŒ ΠΏΠ°Π½Π΅Π»ΠΈ ΠΏΡ€ΠΈΡˆΠ»Π°ΡΡŒ Π΄Ρ‹Ρ€ΠΊΠ°. Π Π°ΠΌΠΊΡƒ Π²Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌ Ρ‚Π°ΠΊΡƒΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ панСль выглядСла ΡƒΡ‚ΠΎΠΏΠ»Π΅Π½Π½ΠΎΠΉ, Ρ‚Π°ΠΊ края Π΄Ρ‹Ρ€ΠΊΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ СстСствСннСй. Для расчСта Ρ€Π΅Π³ΠΈΠΎΠ½Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ SetRegion (листинг 1.52), ΠΎΠ½ вызываСтся всСгда, ΠΊΠΎΠ³Π΄Π° Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ€Π΅Π³ΠΈΠΎΠ½ ΠΎΠΊΠ½Π°.

Листинг 1.52. ΠœΠ΅Ρ‚ΠΎΠ΄ SetRegion, ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π³ΠΈΠΎΠ½ ΠΎΠΊΠ½Π°

procedure TFormHole.SetRegion;

var

 Rgn1, Rgn2: HRGN;

 R, R2: TRect;

begin

 // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ€Π΅Π³ΠΈΠΎΠ½, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΡƒ ΠΎΠΊΠ½Π°

 Rgn1 := CreateRectRgn(0, 0, Width, Height);

 // Нам ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΏΠ°Π½Π΅Π»ΠΈ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ

 // Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ ΡƒΠ³Π»Π° ΠΎΠΊΠ½Π° (Π° Π½Π΅ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ

 // ΡƒΠ³Π»Π° клиСнтской области, ΠΊΠ°ΠΊ это задаСтся свойствами

 // Left ΠΈ Π’ΠΎΡ€). Π€ΡƒΠ½ΠΊΡ†ΠΈΠΉ для получСния смСщСния клиСнтской

 // области ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ ΡƒΠ³Π»Π° ΠΎΠΊΠ½Π° Π½Π΅Ρ‚.

 // ΠŸΡ€ΠΈΠ΄Π΅Ρ‚ΡΡ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ сообщСниСм WM_NCCalcRect

 R2 := Rect(Left, Top, Left + Width, Top + Height);

 Perform(WM_NCCALCSIZE, 0, LParam(@R2));

 // ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ° ΠΈΠ·

 // экранных Π² ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ

 // ΡƒΠ³Π»Π° ΠΎΠΊΠ½Π°

 OffsetRect(R2, -Left, -Top);

 // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΏΠ°Π½Π΅Π»ΠΈ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ

 // Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ ΡƒΠ³Π»Π° клиСнтской области ΠΈ пСрСсчитываСм ΠΈΡ…

 // Π² ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ ΡƒΠ³Π»Π° ΠΎΠΊΠ½Π°

 R := Rect(0, 0, PanelHole.Width, PanelHole.Height);

 OffsetRect(R, PanelHole.Left + R2.Left, PanelHole.Top + R2.Top);

 // ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅ΠΌ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ Π½Π° Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ Ρ€Π°ΠΌΠΊΠΈ ΠΈ создаСм

 // ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π³ΠΈΠΎΠ½

 InflateRect(R, -HoleBorder, -HoleBorder);

 Rgn2 := CreateRectRgnIndirect(R);

 // Π²Ρ‹Ρ‡ΠΈΡ‚Π°Π΅ΠΌ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅Π³ΠΈΠΎΠ½ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ, получая

 // ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ с Π΄Ρ‹Ρ€ΠΊΠΎΠΉ

 CombineRgn(Rgn1, Rgn1, Rgn2, RGN_DIFF);

 // ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅ΠΌ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅Π³ΠΈΠΎΠ½

 DeleteObject(Rgn2);

 // НазначаСм Ρ€Π΅Π³ΠΈΠΎΠ½ с Π΄Ρ‹Ρ€ΠΊΠΎΠΉ ΠΎΠΊΠ½Ρƒ

 SetWindowRgn(Handle, Rgn1, True);

 // ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Ρ€Π΅Π³ΠΈΠΎΠ½, Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹ΠΉ ΠΎΠΊΠ½Ρƒ, Π½ΠΈΠ³Π΄Π΅

 // Π½Π΅ уничтоТаСтся. ПослС выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ SetWindowRgn

 // Ρ€Π΅Π³ΠΈΠΎΠ½ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ систСмы, ΠΈ ΠΎΠ½Π° сама

 // ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠΈΡ‚ Π΅Π³ΠΎ ΠΏΡ€ΠΈ нСобходимости

end;

БообщСния, ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΠ΅ с ΠΏΠ°Π½Π΅Π»ΠΈ, ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· Π΅Π΅ свойство WindowProc (ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ эта тСхнология описана Π² ΠΏΠ΅Ρ€Π²ΠΎΠΉ части Π΄Π°Π½Π½ΠΎΠΉ Π³Π»Π°Π²Ρ‹, здСсь ΠΌΡ‹ Π΅Π΅ ΠΊΠ°ΡΠ°Ρ‚ΡŒΡΡ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ). Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ WM_NCHITTEST Π±ΡƒΠ΄Π΅ΠΌ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈ ΠΏΠΎΠΏΠ°Π΄Π°Π½ΠΈΠΈ ΠΌΡ‹ΡˆΠΈ Π½Π° Ρ€Π°ΠΌΠΊΡƒ ΠΏΠ°Π½Π΅Π»ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π»ΠΈΡΡŒ Ρ‚Π°ΠΊΠΈΠ΅ значСния, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π° эту Ρ€Π°ΠΌΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Ρ‚ΡΠ½ΡƒΡ‚ΡŒ. Π’ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ сообщСния WM_SIZE ΠΏΠ°Π½Π΅Π»ΠΈ измСняСм Ρ€Π΅Π³ΠΈΠΎΠ½ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ соотвСтствовал Π½ΠΎΠ²ΠΎΠΌΡƒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ ΠΏΠ°Π½Π΅Π»ΠΈ. ВсС, Π΄Ρ‹Ρ€ΠΊΠ° с измСняСмыми Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌΠΈ Π³ΠΎΡ‚ΠΎΠ²Π°. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½ΡƒΠΆΠ½ΠΎ Π½Π°ΡƒΡ‡ΠΈΡ‚ΡŒ "Π΄Ρ‹Ρ€ΠΊΡƒ" ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΎΠΊΠ½Π°, Ссли ΠΎΠΊΠ½ΠΎ стало слишком малСньким, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π² сСбя Π΄Ρ‹Ρ€ΠΊΡƒ. ΠžΡΡ‚Π°Π»ΠΎΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ "навСсти красоту". "ΠšΡ€Π°ΡΠΎΡ‚Π°" Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ ΠΌΠΎΠ³ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ Π΄Ρ‹Ρ€ΠΊΠΈ Π΄ΠΎ нуля ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° Π²Ρ‹ΡˆΠ»Π° Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ ΠΎΠΊΠ½Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ ΠΎΠΊΠ½ΠΎ Ρ‚Π°ΠΊ. Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Ρ‹Ρ€ΠΊΠ° оказалась Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ ΠΎΠΊΠ½Π°. ΠŸΠ΅Ρ€Π²Π°Ρ ΠΈΠ· этих Π·Π°Π΄Π°Ρ‡ Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ просто: добавляСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сообщСния WM_SIZING для Π΄Ρ‹Ρ€ΠΊΠΈ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΅Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ Π½Π΅ ΠΌΠΎΠ³Π»ΠΈ ΡΡ‚Π°Ρ‚ΡŒ мСньшС, Ρ‡Π΅ΠΌ MinHoleSize Π½Π° MinHoleSize пиксСлов, Π° Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ нСльзя Π±Ρ‹Π»ΠΎ ΠΏΡ€ΠΈΠ΄Π²ΠΈΠ½ΡƒΡ‚ΡŒ ΠΊ Π³Ρ€Π°Π½ΠΈΡ†Π°ΠΌ ΠΎΠΊΠ½Π° Π±Π»ΠΈΠΆΠ΅, Ρ‡Π΅ΠΌ Π½Π° HoleDistance пиксСлов. Вторая Π·Π°Π΄Π°Ρ‡Π° Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ Π΅Ρ‰Π΅ ΠΏΡ€ΠΎΡ‰Π΅: Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ WM_SIZE Π΄Ρ‹Ρ€ΠΊΠΈ мСняСм свойство Constraints Ρ„ΠΎΡ€ΠΌΡ‹ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ ΠΌΠΎΠ³ слишком сильно ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ ΠΎΠΊΠ½ΠΎ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎΠΊΠ½ΠΎ с Π΄Ρ‹Ρ€ΠΊΠΎΠΉ Π²Π΅Π΄Π΅Ρ‚ сСбя ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΏΡ€ΠΈ Π»ΡŽΠ±Ρ‹Ρ… дСйствиях ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ с Π΄Ρ‹Ρ€ΠΊΠΎΠΉ. ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠΈΠΉΡΡ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΊΠΎΠ΄ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сообщСний ΠΏΠ°Π½Π΅Π»ΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 1.53.

Листинг 1.53. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сообщСний ΠΏΠ°Π½Π΅Π»ΠΈ, ΠΎΠ±Ρ€Π°Π·ΡƒΡŽΡ‰Π΅ΠΉ "Π΄Ρ‹Ρ€ΠΊΡƒ"

procedure TFormHole.PanelWndProc(var Msg: TMessage);

var

 Pt: TPoint;

 R: TRect;

begin

 POldPanelWndProc(Msg);

 if Msg.Msg = WM_NCHITTEST then

 begin

  // Вся Ρ…ΠΈΡ‚Ρ€ΠΎΡΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сообщСния WM_NCHITTEST

  // Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π΅ экранных ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚

  // Π² клиСнтскиС ΠΈ Π² нСсколько ΠΌΡƒΡ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅ попадания

  // ΠΌΡ‹ΡˆΠΈ Π½Π° сторону Ρ€Π°ΠΌΠΊΠΈ ΠΈΠ»ΠΈ Π² Π΅Π΅ ΡƒΠ³ΠΎΠ». Π”Π΅Π»ΠΎ упрощаСтся