• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Winapi

  • Автор темы solova
  • Дата начала
S

solova

Создал совершенно чистый проект.
Нашёл работающий примерчик.
Создаю окошко:
Закрашиваю его: <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Код</div></div><div class="sp-body"><div class="sp-content">
C++:
#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
HWND hWnd; 
MSG lpMsg;
WNDCLASS wc;
wc.style		 = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc  = WndProc;
wc.cbClsExtra	= 0;
wc.cbWndExtra	= 0;
wc.hInstance	 = hInstance;
wc.hIcon		 = NULL;	//LoadIcon(NULL, IDI_ICON);  
wc.hCursor	  = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW+2;//(HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "ClassName";
if (!RegisterClass(&wc))
{
MessageBox(NULL, "Не могу зарегистрировать класс окна!", "Ошибка", MB_OK);
return 0;
}
hWnd = CreateWindow("ClassName",		// Имя класса				  
"Шаблон WinAPI приложения",		 // Текст заголовка
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,		 // Стиль окна												 
50,50,				  // Позиция левого верхнего угла 
300,200,				// Ширина и высота окна	
NULL,					// Указатель на родительское окно NULL	
NULL,					// Используется меню класса окна			 
hInstance,			 // Указатель на текущее приложение
NULL);				 // Передается в качестве lParam в событие WM_CREATE
if (!hWnd){
MessageBox(NULL, "Не удается создать главное окно!", "Ошибка", MB_OK);
return 0;}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Выполняем цикл обработки сообщений до закрытия приложения
while (GetMessage(&lpMsg, NULL, 0, 0)) 
{
TranslateMessage(&lpMsg);
DispatchMessage(&lpMsg);
}
return (lpMsg.wParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT Rect;
HDC hdc, hCmpDC;
HBITMAP hBmp;
switch (message)
{
case WM_PAINT:
GetClientRect(hWnd, &Rect);
hdc = BeginPaint(hWnd, &ps);
// Создание теневогоs контекста для двойной буфферизации
hCmpDC = CreateCompatibleDC(hdc);
hBmp = CreateCompatibleBitmap(hdc, Rect.right - Rect.left,Rect.bottom - Rect.top);
SelectObject(hCmpDC, hBmp);
// Закраска фоновым цветом
LOGBRUSH br;
br.lbStyle = BS_SOLID;
br.lbColor = 0x333333;
HBRUSH brush;
brush = CreateBrushIndirect(&br);
FillRect(hCmpDC, &Rect, brush);
DeleteObject(brush);
// Копируем изображение из теневого контекста на экран
SetStretchBltMode(hdc, COLORONCOLOR);
BitBlt(hdc, 0, 0, Rect.right - Rect.left, Rect.bottom - Rect.top,hCmpDC, 0, 0, SRCCOPY);
// Удаляем ненужные системные объекты
DeleteDC(hCmpDC);
DeleteObject(hBmp);
hCmpDC = NULL;
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return 0;
}
Цвет приятный в окне, но вот его голубая рамка (XP Style) просто раздражает.
Внимание, вопрос!
Можно ли этот цвет поменять\зарисовать как-то?
PS:(если предыдущее не возможно то)я видел окна без sysmenu и рамки, в MFC такое можно сделать установив "Title Bar"-FALSE, как такое создать через CreateWindow ?
 
A

a0z

Нужно обрабатывать сообщения WM_NCPAINT и прочие WM_NC*, которые отвечают за отрисовку неклиентской области окна.
 
S

solova

Ну то что рамка не клиентская область и про WM_NC... я знаю.(перед тем как создавать тему я в нэте роюсь, но ни чего толкового не нашёл)
А как узнать HDC этой области.
и ещё , для окна(Кл. область) используется FillRect(hCmpDC, &Rect, brush); а для рамки то надо?

И вообще я со всякими отрисовками и HBRUSH-ами в первые сталкиваюсь поэтому мне бы как то по подробнее.
Этот код не мой, поэтому хочу спросить, а создавать "теневой контекст для двойной буфферизации" надо обязательно или можно просто сразу зарисовать мой "hdc"? тогда просто HBITMAP hBmp; не нужен будет.
 
L

lazybiz

Создай окно со одним стилем WS_POPUP.
 
S

solova

lazybiz
ну как бы то что нужно
только его двигать нельзя
WMPlayer 11 без рамки(хотя её можно включить) но там как то реализуется убирание этой рамки окно выглядит как попуп, но его двигать можно.
 
A

a0z

А как узнать HDC этой области.
GetWindowDC

и ещё , для окна(Кл. область) используется FillRect(hCmpDC, &Rect, brush); а для рамки то надо?
Да всё тоже самое.

Этот код не мой, поэтому хочу спросить, а создавать "теневой контекст для двойной буфферизации" надо обязательно или можно просто сразу зарисовать мой "hdc"? тогда просто HBITMAP hBmp; не нужен будет.
Не обязательно, но может напиятно моргать и дёргаться.

Хотя, если стиль тулбара устраивает, то можно не мучаться. А перемещения отрабатывать через WM_LBUTTONDOWN/WM_LBUTTONUP + GetCapture
 
L

lazybiz

solova
1. Смотри. Создаешь окно со стилем WS_POPUP.
2. В процедуре окна прописываешь следующее на обработчик сообщений:
C++:
case WM_NCHITTEST: return HTCAPTION;
 
L

lazybiz

И еще:
При срабатывании WM_NCHITTEST, lParam имеет: в нижнем слове - координату X курсора, в верхнем - Y --- относительно верхнего-левого угла экрана! НЕ ОКНА!
Т.е., можно координаты экрана преобразовать в пространство окна и задать область.. скажем в 32 пикселя от верхней границы окна:
C++:
	case WM_NCHITTEST: {
POINT	pt;
pt.x = LOWORD( lParam );
pt.y = HIWORD( lParam );
ScreenToClient( hWnd, &pt );
if ( pt.y < 32 ) return HTCAPTION;
} break;
 
S

solova

ещё один вопросик
как сделать обработчик кнопки
собсно сама кнопка
C++:
CreateWindowEx(NULL,L"Button",L"Button1",WS_VISIBLE|WS_CHILD,10, 70, 90, 40,hWnd,IDB_Button1, hInstance, NULL );
в мфц там проще но тут пока не знаю как
думаю отлавливать WM_COMAND. Можно(а может нужно) как-то по другому?

а ну вот всё получилось<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content">
C++:
#define IDB_Button1 1
...
case WM_COMMAND:
if(wParam == IDB_Button1)
MessageBox(NULL,L"Нажата кнопка Button 1",L"Message WM_COMMAND",MB_OK);
 
L

lazybiz

Почти все как ты написал, только немного проще:
C++:
...
case WM_COMMAND:
...
switch ( LOWORD( wParam ) ) {
...
case IDB_Button1:
MessageBox( NULL, L"Нажата кнопка Button 1", L"Message WM_COMMAND", MB_OK );
break;

...
} break;
...
...
На всякий случай увеличь значение идентификатора IDB_Button1 например:
C++:
#define IDB_Button1 1001

И еще. Зачем создавать кнопку через CreateWindowEx, если расширенный стиль (первый параметр) у тебя выставлен в NULL ? Функция CreateWindowEx отличается от CreateWindow только только тем что у нее есть параметр расширенного стиля.
 
S

solova

Зачем создавать кнопку через CreateWindowEx, если расширенный стиль (первый параметр) у тебя выставлен в NULL
у меня был там параметр но тут я его убрал для лучшей читабельности кода.
На всякий случай увеличь значение идентификатора IDB_Button1 например:
#define IDB_Button1 1001
а к чему может привести маленький ID? (может присваивать какой то "WM_USER+..." ?)

а switch в WM_COMMAND буду использовать позже, когда кнопок будет больше
спасибаа
 
L

lazybiz

а к чему может привести маленький ID?
В WM_COMMAND скорее всего ни к чему, хотя черт его знает...

может присваивать какой то "WM_USER+..."
Нннет. Смысл схож но не совсем то. WM_USER + X - это если ты добавляешь какое-то свое сообщение непосредственно окну, а тут ты добавляешь идентификатор кнопки. Все-таки немного разные вещи.

Пожалуйста.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!