Твои обои - твоя крепость!

Автор: Lexxxa

HI/low, mY dear }{аЦкERRzzz!
Сегодня мы займемся обоями. Гы... Разведем белую кашу и начнем клеить ;-) Какая тупая тема, но надо с чего-то начать. Вот есть у вас например злобный брат, котрый постоянно меняет ваших голых теток на рабочем столе на какой-нить скриншот из игры. И вас это бесит. Чё? Нету брата? Оке! Есть институт - там такие =админы= сидят, что кого угодно взбесят! И обои им не меняй, и музыку на парах не слушай - грех западлу не сделать! Но вернемся к брату ;-) Он нас бесит. Вывод? Не... В морду бить не будем. Не наш метод. ;-) Лучше напишем прогу, которая будет постоянно висеть (в хорошем смысле слова :-) и смотреть, не променяли-ли наших теток на ламерские игры. Как это сделать? На самом деле очень просто. Все примеры будут даны на Builder C++. Но если у вас в голове не тоже самое что у дятла Вини-Пука то без проблем все переделаете под Дельфу. Можете под QBasic попробовать ;-)

Приступим. Первое. Нашу прогу не должно быть видно. Иначе даже последний ламер (а ведь наш брат последний ламер ;-) сможет нажать три свои любимые кнопочки и увидев задачу "Super-krutoi oblamywatel lyubitelei menyat oboi" с радостью нажмет кнопочку "Завершить задачу" и сменит все-таки наших теток. Да, потом еще побежит хвастаться что хакнул нашу прогу. Такие они ламеры ;-) И не надо кричать: "Назовем прогу mssys32!". Мы пойдем другим путем! Нафиг нам вся эта ламерщина? Поюзаем библиотечку kernell32.dll там есть полезные функции.
Cейчас нас интересует следующее:


HINSTANCE hInstKernel;
DWORD (__stdcall *pRegisterServiceProcess)(DWORD, DWORD);
hInstKernel = LoadLibrary ("KERNEL32.DLL");
if (hInstKernel)
{
    pRegisterServiceProcess = (DWORD (__stdcall *) (DWORD, DWORD)) GetProcAddress (hInstKernel,     "RegisterServiceProcess");
    if (pRegisterServiceProcess)
    {
        pRegisterServiceProcess (NULL, 1);
    }
    FreeLibrary (hInstKernel);
}

Все это вставлять в функцию WinMain (файл Project1.cpp) в начало блока try.

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
   try
   {
        HINSTANCE hInstKernel;

и т.д.

Не забудтьте тут же прописать
Application->ShowMainForm = FALSE;

Все, теперь в списке задач нашу прогу не будет видно (под 9х окнами). Можно заняться тем чем мы изначально и собирались заняться. Отслеживать изменения обоев и ставить наши назад. Сначала поумаем. Это полезное занятие. Подумали. Пускай например наши обои будут лежать в файлике с:\windows\1.bmp . Чтобы определить путь к каталогу с МастДаем поюзаем функцию GetWindowsDirectory(char*lpBuffer, unsigned int uSize) Теперь напишем небольшую функцию по чтению данных из реестра. Так будет удобнее. У меня она выглядит так:
String WallPaper::Read(String root, String path, String property)
{
    String data;
    TRegistry *pReg = new TRegistry;
    pReg->RootKey=HKEY_USERS;
    if (root=="HKEY_LOCAL_MACHINE")    pReg->RootKey=HKEY_LOCAL_MACHINE;
    pReg->OpenKey(path, true);
    data=pReg->ReadString(property);
    return data;
}

Так как мы будем читать данные только из HKEY_USERS и HKEY_LOCAL_MACHINE то можно оставить все так. Если надо будет использовать еще что-то, то надо будет написать другую функцию для смены RootKey. Можете константы ввести. В общем, если кому надо - сам допрет. Мы рассматриваем только общие моменты.
Напишем еще пару методов.
void WallPaper::SetWallpaper(String str)
{
    SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, str.c_str(), True);
}

void WallPaper::SaveString(String strPath , String strValue , String strdata)
{
    TRegistry *pReg = new TRegistry;
    pReg->RootKey= HKEY_LOCAL_MACHINE ;
    pReg->OpenKey(strPath, true);
    pReg->WriteString(strValue,strdata);
}

Ну вот. Теперь можно написать основную часть программы. Во-первых поместите на форму таймер. Интервал установите каким хотите. Хотите, чтобы брат обламывался через минуту после смены обоев - ставьте минуту. Хотите немедленно - поставьте секунду. Ну и сама функция собсна:


void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    String strString = test.Read("HKEY_USERS", ".Default\\Control Panel\\Desktop", "Wallpaper");
    // WinDir - наша переменная полученияс помощью функции GetWindowsDirectory(char*, unsigned int)
    if (strString != WinDir + "\\1.bmp") //если текущие обои не наши
    {
        test.SetWallpaper (WinDir + "\\1.bmp"); //ставим наши
    }

    strString = test.Read("HKEY_LOCAL_MACHINE", "\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "RealAPlayer");
    if (strString != Application->ExeName) //если нашу программу стерли из автозагрузки (RealAPlayer - можете поменять по желаниб на любое другое название раздела)
        test.SaveString("Software\\Microsoft\\Windows\\CurrentVersion\\Run", "RealAPlayer", Application->ExeName); //помещаем ее назад

    if (!FileExists(WinDir+"\\1.bmp")) //если же не дай бог стерли файл с нашими тетками!
    {
        //записываем теток из ресурсов нашей проги в файлик.
        // Чтобы добавить файл в ресурсы зайдите в меню Project -> Resources

        Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap();
        Bitmap1->LoadFromResourceName((int)HInstance, "BITMAP_1"); //BITMAP_1 - наш файл.
        Bitmap1->SaveToFile(WinDir+"\\1.bmp"); // сохраняем на диск
    }
}

Ну вот вроде бы и все.
Теперь немного бреда.
Можете поэксперементировать с прогой. Как? Ну подключите фантазию ;-) Например можно захватить экран, поставить его как обои и убрать панельку с кнопкой "пуЦк". Ламер долго будет кликать по ярлычкам :-) В общем экспериментируйте mY dear }{аЦкERRzzz.

Сия текста по идее была написана для людей более-менее знакомых с Builder'ом. В общем, если вы умеете размещать Timer на форме - то можете попытаться сделать и фсе остальное :-) Ну если возникнут вопросы, пожелания etc - пишите. Да помидорами очень гнилыми не кидать! Это моя первая статья.

В заключение могу сказать, что все это не ново. Но в основном все написано под Дельфу - вот я и решил "порадовать" продвинутых...гы... кодеров на славном Цэ++. Можете подкинуть идеи для следующих статей. На сегодня усе. Рэгхламент!