Քաշեք Դելֆիի ձև ՝ առանց վերնագիրների տողի

Քաշեք Դելֆիի ձև ՝ առանց վերնագիրների տողի

Պատուհանը տեղափոխելու ամենատարածված ձևն այն է վերնագրի սանդղակը քաշել: Կարդացեք ՝ պարզելու համար, թե ինչպես կարող եք տրամադրել Դելֆիի ձևերի համար առանց քաշային տողի ձգման հնարավորություններ, այնպես որ օգտագործողը կարող է ձևաթուղթ տեղափոխել ՝ կտտացնելով հաճախորդի տարածքում ցանկացած տեղ:

Օրինակ ՝ հաշվի առեք Windows- ի դիմումի այն դեպքը, որը չունի վերնագրի տող, ինչպե՞ս կարող ենք նման պատուհանը տեղափոխել: Փաստորեն, հնարավոր է ստեղծել պատուհաններ ոչ ստանդարտ տիտղոսաթերթով և նույնիսկ ոչ ուղղանկյուն ձևերով: Այս դեպքում ինչպե՞ս կարող էր Windows- ն իմանալ, թե որտեղ են պատուհանի սահմաններն ու անկյունները:

WM_NCHitTest Windows- ի հաղորդագրությունը

Windows օպերացիոն համակարգը մեծապես հիմնված է հաղորդագրությունների բեռնաթափման վրա: Օրինակ, երբ կտտացնում եք պատուհանի կամ հսկողության վրա, Windows- ն այն ուղարկում է wm_LButtonDown հաղորդագրություն ՝ լրացուցիչ տեղեկություններ այն մասին, թե որտեղ է մկնիկի կուրսորը և որի վերահսկման ստեղները ներկայումս սեղմված են: Հնչում է ծանոթ: Այո, սա ոչ այլ ինչ է, քան Դելֆիում OnMouseDown միջոցառումը:

Նմանապես, Windows- ն ուղարկում է wm_NCHitTest հաղորդագրություն, երբ մկնիկի իրադարձություն է տեղի ունենում, այսինքն, երբ կուրսորը շարժվում է, կամ երբ մկնիկի կոճակը սեղմվում է կամ ազատվում:

Մուտքագրման կոդ

Եթե ​​մենք կարող ենք ստիպել Windows- ին մտածել, որ օգտագործողը քաշում է (կտտացրել է) վերնագրի սանդղակը, քան հաճախորդի տարածքը, ապա օգտագործողը կարող է քաշել պատուհանը `կտտացնելով հաճախորդի տարածքում: Դա կատարելու ամենադյուրին ճանապարհը Windows- ը «հիմարացնելն» է ՝ մտածելով, որ իրականում կտտացնում եք որևէ ձևի վերնագրի սանդղակը: Ահա այն, ինչ դուք պետք է անեք.

1. Ձեր ձևի «Մասնավոր հայտարարագրեր» բաժնում տեղադրեք հետևյալ տողը (հաղորդագրությունների վարման կարգի հայտարարություն).

կարգը WMNCHitTest (var Msg: TWMNCHitTest); հաղորդագրությունը WM_NCHitTest;

2. Ձեր ձևի միավորի «իրականացման» բաժնում լրացրեք հետևյալ ծածկագիրը (որտեղ ձև 1-ը ենթադրյալ ձևի անունն է).

կարգը TForm1.WMNCHitTest (var Msg: TWMNCHitTest);

սկսվում է

   ժառանգել է;
  

եթե Msg.Result = htClient ապա Msg.Result: = htCaption;

վերջ;

Հաղորդագրության վարիչի առաջին տողը կոչում է ժառանգված մեթոդ ՝ wm_NCHitTest հաղորդագրության համար ստանդարտ բեռնաթափում ստանալու համար: Ընթացակարգի Եթե մասն ընդհատում և փոխում է ձեր պատուհանի պահվածքը: Սա այն է, ինչ տեղի է ունենում իրականում. Երբ գործավար համակարգը մկնիկի կոորդինատների հետ միասին wm_NCHitTest հաղորդագրություն է ուղարկում պատուհանի, ապա պատուհանը վերադարձնում է այնպիսի ծածկագիր, որը նշում է, թե որ հատվածում է հայտնվել: Տեղեկատվության կարևոր մասը, մեր առաջադրանքի համար, Msg.Result դաշտի արժեքի մեջ է: Այս պահին մենք հնարավորություն ունենք փոփոխել հաղորդագրության արդյունքը:

Սա այն է, ինչ մենք անում ենք. Եթե օգտագործողը կտտացրել է ձևի հաճախորդի տարածքում, մենք Windows- ը ստիպում ենք մտածել, որ օգտագործողը կտտացրել է վերնագրի սանդղակը: Object Pascal- ի «բառերը». Եթե հաղորդագրության վերադարձի արժեքը HTCLIENT է, մենք այն պարզապես փոխում ենք HTCAPTION:

Այլևս մկների իրադարձություններ չկան

Մեր ձևերի լռելյայն պահվածքը փոխելով `մենք հեռացնում ենք Windows- ի հնարավորությունը` ձեզ տեղեկացնելու մասին, երբ մկնիկը անցնում է հաճախորդի տարածքում: Այս հնարքի մի կողմնակի ազդեցությունն այն է, որ ձեր ձևը այլևս չի առաջացնի մկնիկի հաղորդագրությունների իրադարձություններ:

Առակ-անսահման պատուհան

Եթե ​​ցանկանում եք ունենալ անլար առանց սահմանի պատուհան, որը նման է լողացող գործիքագոտու, ապա Ձևի վերնագիրը դրեց դատարկ տողի վրա, անջատեք բոլոր BorderIcons- ը և սահմանեք BorderStyle- ը bsNone- ով:

Ձևաթուղթը կարելի է տարբեր ձևերով փոխել ՝ օգտագործելով մաքսային ծածկագիր ՝ CreatParams մեթոդով:

Ավելին WM_NCHitTest հնարքներ

Եթե ​​ավելի ուշադիր նայեք wm_NCHitTest հաղորդագրությանը, կտեսնեք, որ գործառույթի վերադարձման արժեքը ցույց է տալիս կուրսորի թեժ կետի դիրքը: Սա մեզ հնարավորություն է տալիս ավելի շատ խաղալ հաղորդագրության հետ `տարօրինակ արդյունքներ ստեղծելու համար:

Հետևյալ կոդերի հատվածը թույլ կտա օգտվողներին փակել ձեր ձևերը `կտտացնելով Close կոճակը:

եթե Msg.Result = htClose ապա Msg.Result: = htNowhere;

Եթե ​​օգտագործողը փորձում է տեղափոխել ձևը `կտտացնելով վերնագրերի սանդղակը և քարշ տալով, ծածկագիրը փոխարինում է հաղորդագրության արդյունքին այն արդյունքով, որը ցույց է տալիս, որ օգտվողը կտտացրել է հաճախորդի տարածքում: Սա կանխում է օգտագործողին մկնիկի հետ պատուհանը տեղափոխել (հակառակ այն բանի, ինչ մենք անում էինք հոդվածի մուրացման ժամանակ):

եթե Msg.Result = htCaption ապա Msg.Result: = htClient;

Բաղադրիչներ ունենալով մի ձևի վրա

Շատ դեպքերում, մենք կունենանք որոշ բաղադրիչներ որևէ ձևի վրա: Եկեք ասենք, օրինակ, որ Panel- ի մեկ առարկա ձևի վրա է: Եթե ​​վահանակի հավասարեցումը հավասարեցված է AlClient- ին, Պանելը լրացնում է հաճախորդի ամբողջ տարածքը, այնպես որ անհնար է ընտրել ծնողի ձևը `կտտացնելով այն: Վերը նշված ծածկագիրը չի գործի, ինչու՞: Դա այն է, որ մկնիկը միշտ շարժվում է Panel- ի բաղադրիչով, այլ ոչ թե ձևով:

Մեր ձևը վահանակի վրա սևեռելու համար մենք պետք է ավելացնել մի քանի տող ծածկագիրներ OnMouseDown միջոցառման ընթացակարգում `Panel բաղադրիչի համար.

կարգը TForm1.Panel1MouseDown
(Ուղարկող ՝ TObject; կոճակ ՝ TMouseButton;
Shift: TShiftState; X, Y: Հետաքրքրություն);

սկսվում է

ReleaseCapture;

SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);

վերջ;

ՆշումԱյս ծածկագիրը չի աշխատի ոչ պատուհանների կառավարման հետ, ինչպիսիք են TLabel- ի բաղադրիչները: