доброго времени суток)) и всех с наступившим Новым Годом) как заголовок окна сделать прозрачным?) в принципе я знаю, как перерисовать сам заголовок, средствами winapi. а как же сделать его прозрачным? блин понять до сих пор не могу((( ОС: Windows XP SP3
получать текст под окном, потом сумировать сцета по спец алгоритму чтобы добиться прозрачности и рисовать где надо
мне никто не помог, а я селал) но сделал лажу, которая проц жрет страшно Code: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls; type TForm1 = class(TForm) img1: TImage; btn1: TBitBtn; tmr1: TTimer; procedure FormCreate(Sender: TObject); private { Private declarations } procedure WMEnterSizeMove(var Msg:TMessage);message WM_EnterSizeMove; procedure WMExitSizeMove(var Msg:TMessage);message WM_ExitSizeMove; procedure WMPaint(var Msg: TWMPaint); message WM_Paint; procedure WMMove(var Msg:TMessage);message WM_Move; public { Public declarations } end; var Form1: TForm1; BM1, BM2 : TBitmap; Transparency:Integer = 60; TranspColor: TColor = clBlue; Moving : Boolean; type PRGBArray=^TRGBArray; TRGBArray=array[0..1000000] of TRGBTriple; implementation {$R *.dfm} procedure Delay(DelayTime:Integer); var TicksNow:Integer; begin TicksNow:=GetTickCount; repeat Application.ProcessMessages until GetTickCount - TicksNow >= DelayTime end; // Получение контекста заголовка окна procedure GetWindowTitleDC(Wnd: THandle; ADC: HDC); var Dc : HDC; // Контекст устройсва Rect : TRect; // Прямоугольник окна begin // Получем контекст окна Dc := GetWindowDC(Wnd); // Получаем прямоугольник окна GetWindowRect(Wnd, Rect); // Записываем полученное изображение и отдаем его BitBlt(ADC, 0, 1, Rect.Right, 25, Dc, 0, 1, SRCCOPY); // Контекст нам больше ненужен, о чем мы и сообщаем ReleaseDC(Wnd, Dc); end; // Задаем картинку заголовку procedure SetWindowTitleImage(Wnd: THandle; szImage: TBitmap); var DC : HDC; CA : TCanvas; Rect : TRect; PWi : tagWINDOWINFO; begin DC := GetWindowDC(Wnd); // Получаем контекст окна CA := TCanvas.Create; CA.Handle := DC; GetWindowRect(Wnd, Rect); GetWindowInfo(Wnd, PWi); // Срезаем изображение Rect.Bottom := 25; Rect.Top := 0; Rect.Left := 0; Rect.Right := PWi.rcWindow.Right - PWi.rcWindow.Left; // Отрисовываем изображение CA.Draw(0, 0, szImage); ReleaseDC(Wnd, DC); // Сообщаем винде, что данный контекст более не требуеся CA.Free; // Убиваем канву end; procedure TForm1.WMPaint; var DC : HDC; // Контекст устройства Rect : TRect; // Прямоугольник окна PWi : tagWINDOWINFO; // Информация об окне X, Y : Integer; // Позиции по ширине и высоте CW, CH : Integer; // Ширина и высота SL : PRGBArray; // Указатель на строку писелей CA : TCanvas; begin // Считываем координаты окна GetWindowRect(Handle, Rect); GetWindowInfo(Handle, PWi); BM2.Width := Rect.Right; BM2.Height := 25; BM2.PixelFormat := pf24bit; BitBlt(bm2.Canvas.Handle, 0, 0, BM1.Width, BM1.Height, BM1.Canvas.Handle, Rect.Left, Rect.Top, SRCCOPY); DC := GetWindowDC(Handle); // Получаем контекст окна CA := TCanvas.Create; CA.Handle := DC; for Y :=0 to bm2.height -1 do begin SL:=BM2.ScanLine[Y]; for X:=0 to BM2.Width -1 do begin SL[X].rgbtRed:=(Transparency*SL[X].rgbtRed+(100-Transparency)*GetRValue(TranspColor)) div 100; SL[X].rgbtGreen:=(Transparency*SL[X].rgbtGreen+(100-Transparency)*GetGValue(TranspColor)) div 100; SL[X].rgbtBlue:=(Transparency*SL[X].rgbtBlue+(100-Transparency)*GetBValue(TranspColor)) div 100 end end; // Отрисовываем изображение CA.Draw(0, 0, BM2); Msg.DC := dc; inherited; ReleaseDC(Handle, DC); // Сообщаем винде, что данный контекст более не требуеся CA.Free; // Убиваем канву end; procedure TForm1.FormCreate(Sender: TObject); var dc: hdc; begin BM1 := TBitmap.Create; { Тут будет храниться изображение экрана } BM2 := TBitmap.Create; Moving := False; // Задаем размеры изображения по размеру экрана BM1.Width := GetSystemMetrics(SM_CXSCREEN); BM1.Height := GetSystemMetrics(SM_CYSCREEN); BM1.PixelFormat := pf24bit; DC := GetDC(0); // Получаем контекст дисплея // Закидываем контекст в изображение BitBlt(BM1.Canvas.Handle, 0, 0, BM1.Width, BM1.Height, DC, 0, 0, SRCCOPY); // Контекст больше не требуется, сообщаем винде, // что он свободен и передаем его дальше ReleaseDC(Handle, DC); end; procedure TForm1.WMMove; begin Invalidate; // Всё, пора перерисовываться inherited end; procedure TForm1.WMEnterSizeMove; begin Moving:=True; inherited end; procedure TForm1.WMExitSizeMove; begin inherited; Moving:=False end; end. если кто сможет улучшить производительность, скиньте норм вариант )) плиииз) всех с нг))
Яжжж, тебе писал уже. Code: #include <windows.h> #include <tchar.h> #include <GdiPlus.h> #pragma comment(lib, "GdiPlus.lib") using namespace Gdiplus; // тут ловчей структуру сделать #define RAMKA_H 300 #define RAMKA_W 500 HWND hRamka; HWND hMainWindow; //-------------------------------------------------------------------------------- LRESULT CALLBACK RamkaProc(HWND hWnd,UINT Message, UINT wParam, LONG lParam) { switch(Message) { case WM_ACTIVATE: // если у нас активизировалось окошко, то активизируем главное окно if((LOWORD(wParam)==WA_CLICKACTIVE || LOWORD(wParam)==WA_ACTIVE) && (HWND)lParam==hMainWindow) { SetActiveWindow(hMainWindow); return 0; } break; case WM_PAINT:{ PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps); // наведем красоту в виде округленных уголков // рисуем сначала прозрачные прямоугольники, а потом врисовываем черные элипсы :) Graphics g(hDC); RectF top_left(0.0f, 0.0f, 5.0f, 5.0f); RectF bottom_left(0.0f,(ps.rcPaint.bottom-ps.rcPaint.top)-5.0f, 5.0f, 5.0f); RectF top_right((ps.rcPaint.right-ps.rcPaint.left)-5,0.0f, 5.0f, 5.0f); RectF bottom_right((ps.rcPaint.right-ps.rcPaint.left)-5,(ps.rcPaint.bottom-ps.rcPaint.top)-5, 5.0f, 5.0f); RectF rects[4] = {top_left, bottom_left,top_right,bottom_right}; SolidBrush sBrush(Color(255,255,255)); SolidBrush sBrush2(Color(0,0,0)); Pen pen(&sBrush, 1); g.FillRectangles(&sBrush,rects,4); for(int i=0;i<4;i++) { rects[i].Width=rects[i].Height=10; if(i>1) { rects[i].X-=6; } if(((i+1)%2)==0) { rects[i].Y-=6; } g.FillEllipse(&sBrush2,rects[i]); } EndPaint(hWnd, &ps); return 0; } case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,Message,wParam,lParam); } LRESULT CALLBACK MainWinProc(HWND hWnd,UINT Message, UINT wParam, LONG lParam) { switch(Message) { case WM_ACTIVATE: if(LOWORD(wParam)==WA_ACTIVE && (HWND)lParam!=hRamka) { SetForegroundWindow(hRamka); } // передаем управление рамке break; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,Message,wParam,lParam); } int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); WNDCLASS WndClass; TCHAR szClassName[]=_TEXT("lol"); TCHAR szClassName2[]=_TEXT("lol2"); WndClass.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC; WndClass.lpfnWndProc=RamkaProc; WndClass.cbClsExtra=0; WndClass.cbWndExtra=0; WndClass.hInstance=hInstance; WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION); WndClass.hCursor=LoadCursor(NULL,IDC_ARROW); WndClass.hbrBackground=CreateSolidBrush(0x000000); WndClass.lpszMenuName=NULL; WndClass.lpszClassName=szClassName; if(!RegisterClass(&WndClass)) { MessageBox(NULL,_TEXT("Невозможно создать класс"),NULL,MB_OK|MB_ICONERROR); return 0; } // вычисление координат центра экрана RECT screen_rect; GetWindowRect(GetDesktopWindow(),&screen_rect); // разрешение экрана int x = screen_rect.right / 2 - RAMKA_W / 2; int y = screen_rect.bottom / 2 - RAMKA_H / 2; hRamka=CreateWindowEx(WS_EX_LAYERED|WS_EX_TOOLWINDOW,szClassName,NULL,WS_POPUP, x,y, RAMKA_W,RAMKA_H, NULL,NULL, hInstance,NULL); if(!hRamka) { MessageBox(NULL,_TEXT("Невозможно создать окно"),NULL,MB_OK|MB_ICONERROR); return 0; } // создаем прозрачное окно и делаем белый цвет практически прозрачным SetLayeredWindowAttributes(hRamka, 0xFFFFFF, 50, LWA_ALPHA|LWA_COLORKEY); WndClass.lpszClassName=szClassName2; WndClass.hbrBackground=CreateSolidBrush(0xFFFFFF); WndClass.lpfnWndProc=MainWinProc; RegisterClass(&WndClass); hMainWindow=CreateWindow(szClassName2,NULL,WS_POPUP|WS_VISIBLE,x+10,y+10,RAMKA_W-20,RAMKA_H-20,NULL,NULL,hInstance,NULL); ShowWindow(hRamka, nShowCmd); SetActiveWindow(hMainWindow); MSG Msg; while(GetMessage(&Msg,NULL,0,0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } GdiplusShutdown(gdiplusToken); return (int)Msg.wParam; } результат на лицо
Вот заморочился и написал свой первый в жизни класс на С++, который упрощает код опубликованный выше. [БРАТЬ ЗДЕСЬ] Юзать просто: Code: #include "theme.hpp" int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // ширина, высота, размер рамки, цвет рамки, прозрачность от 0 до 255 Theme window(500,300,10,0x000000,50); window.Create(); MSG Msg; while(GetMessage(&Msg,NULL,0,0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return (int)Msg.wParam; } Пока правда одно окно можно делать, но сейчас может попробую модифицировать на диалоги