Неизползвани опции, разширяване на контекстното меню за бутони в лентата на задачите и др.

Въпрос попаднах на C ++ - код, където UNREFERENCED_PARAMETER се използва за неизползвани параметри, например:

int SomeFunction (int arg1, int arg2)

Но имаше и код като този:

int SomeFunction (int arg1, int/* arg2 * /)

Бихте ли обяснили каква е разликата и кое е по-добро?

Джуди Макги

Отговор Добре, разбира се. Нека започнем с UNREFERENCED_PARAMETER. Това е макросът, дефиниран в winnt.h:

#define UNREFERENCED_PARAMETER (P) (P)

Въпреки това никъде не използвате x. Този ред може да е останал от времето, когато всъщност сте използвали x, но след това сте изтрили част от кода и сте забравили за тази променлива. Предупрежденията от ниво 4 помагат да се открият такива малки пропуски. И така, защо не позволите на компилатора да ви помогне да постигнете най-високо ниво на професионализъм? Успешната компилация с предупреждения от ниво 4 ви кара да се чувствате горди от работата си. Проблемът е, че с ниво 4 компилаторът се оплаква от напълно безвредни неща, например неизползвани параметри (разбира се, те са безвредни само ако наистина не ги използвате). Да приемем, че имате функция с два аргумента, но използвате само един от тях:

int SomeFunction (int arg1, int arg2)
връщане arg1 + 5;
>

С/W4 компилаторът ще докладва: "предупреждение C4100: 'arg2': необозначен формален параметър". За да подведете компилатора, можете да добавите UNREFERENCED_PARAMETER (arg2). Сега вашата функция се позовава на arg2 и компилаторът ще млъкне. И тъй като изразът:

не прави нищо, компилаторът няма да генерира никакъв код за него, така че няма да загубите нито по размер, нито по ефективност.

Острите умове може да се чудят: ако arg2 не се използва, тогава защо изобщо да го декларирам? Това обикновено се прави при внедряване на функция, която трябва да съответства на специфичен API подпис, предаден отгоре. Например манипулаторът на MFC OnSize трябва да има следния подпис:

void OnSize (UINT nType, int cx, int cy);

Тук cx и cy са новата ширина и височина на прозореца, а nType е някакъв код като SIZE_MAXIMIZED, ако прозорецът трябва да бъде напълно разширен, или SIZE_RESTORED, ако е с нормален размер. Като цяло не ви е грижа за nType - грижите се само за cx и cy. Следователно, когато компилирате с превключвателя/W4, имате нужда от UNREFERENCED_PARAMETER (nType). Но OnSize е само една от хилядите функции в MFC и Windows. Така че е доста трудно да се напише програма за Windows без параметри, които не са препратени.

void CMyWnd: OnSize (UINT/* nType * /,
int cx, int cy)
>

NType вече е неназован параметър; бихте получили същото нещо, като напишете OnSize (UINT, int cx, int cy). И сега въпрос за $ 64 000: кой начин бихте използвали - неназован параметър или UNREFERENCED_PARAMETER?

Това обикновено няма значение; изборът се определя от стила. (Обичате ли черно кафе или със сметана?) Но мога да измисля поне една ситуация, при която е необходим UNREFERENCED_PARAMETER. Да приемем, че сте решили да предотвратите разширяването на прозореца до целия работен плот. Деактивирате бутона Maximize, премахвате командата Maximize от системното меню и деактивирате всички други контроли, които биха позволили прозореца да бъде максимално увеличен. Тъй като сте параноик (което е повечето добри програмисти), добавяте ASSERT израз, за ​​да сте сигурни, че вашият код работи по предназначение:

void CMyWnd: OnSize (UINT nType, int cx, int cy)
ASSERT (nType! = SIZE_MAXIMIZE);
. // използвайте cx, cy
>

Преди да закръгля, не мога да не спомена, че отделните предупреждения на компилатора могат да бъдат потиснати с директивата за предупреждение pragma:

#pragma предупреждение (деактивиране: 4100)

4100 е кодът за грешка за неизползван параметър. Тази директива засяга останалата част от файла или модула. За да активирате отново това предупреждение:

#pragma предупреждение (по подразбиране: 4100)

По-добре е обаче да запазите състоянието на всички предупреждения, преди да деактивирате някое от тях, а след това, след като сте направили това, от което имате нужда, да се върнете към предишната конфигурация. Тогава ще можете да възстановите предишните си настройки, а не конфигурацията на компилатора по подразбиране.

Можете да потиснете предупрежденията за неизползвани параметри в рамките на една функция, като го заобиколите с предупредителни директиви прагма:

#pragma предупреждение (натискане)
#pragma предупреждение (деактивиране: 4100)
void SomeFunction (.)
>
#pragma предупреждение (поп)

Разбира се, това би било твърде досадно за неизползвани параметри, но вероятно е необходимо за други видове предупреждения. Разработчиците на библиотеки постоянно използват предупреждение #pragma, за да блокират предупреждения, така че кодът им да може да се компилира без проблеми с превключвателя/W4. MFC е пълен с такива прагми. Предупредителните директиви #pragma имат много повече параметри, отколкото споменах тук. Вижте ги в документацията.

Въпрос Забелязах, че в някои приложения има специални команди, които се появяват в контекстното меню за бутоните на такива приложения в лентата на задачите. Например WinAmp (популярен медиен плейър) добавя подменю "WinAmp" със специфични за WinAmp команди. Как да добавя свои собствени команди за бутона за приложение в лентата на задачите?

Джираир Осигиан

Въпрос Създадох просто приложение MFC SDI с формуляр, който показва брояч. Трябва да стартирам и спра брояча, като щракнете с десния бутон върху иконата на приложението, минимизирана до бутон в лентата на задачите. Функциите за стартиране и спиране работят чудесно като бутони на моя формуляр и успях да добавя подобни команди към системното меню. Но когато ги избера от системното меню, нищо не се случва. Как да боравите със съобщения от модифицирано системно меню?

Моник Шарман