FrameRgn
-
Hi!
Ich habe folgenden Code:try { const int ellipticWidth=50; CRgn rgn; CRect rect; CBrush brush(RGB(255, 0, 0)); CDC *dc=GetDC(); if(!dc) throw(1); GetWindowRect(rect); rect.NormalizeRect(); if(!rgn.CreateRoundRectRgn(0, 0, rect.right-rect.left, rect.bottom-rect.top, ellipticWidth, ellipticWidth)) throw(1); if(!dc->FrameRgn(&rgn, &brush, 20, 20)) throw(1); if(!SetWindowRgn(rgn, true)) throw(1); } catch(...) { MessageBox("err caught"); }
Bei der Ausführung erhalte ich keine Exception. Die Region wird problemlos übernommen. Nur FrameRgn funktioniert nicht so ganz, es erscheint kein Rahmen... woran liegt das?
lg, phreaking
-
Erstmal MSDN lesen, oder ?
After a successful call to SetWindowRgn, the system owns the region specified by the region handle hRgn. The system does not make a copy of the region. Thus, you should not make any further function calls with this region handle. In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.
-
So habe ich auch nicht viel mehr Erfolg:
try { const int ellipticWidth=50; CRgn *rgn=new CRgn; CRect rect; CBrush brush(RGB(255, 0, 0)); CDC *dc=GetDC(); if(!dc) throw(1); GetWindowRect(rect); rect.NormalizeRect(); if(!rgn->CreateRoundRectRgn(0, 0, rect.right-rect.left, rect.bottom-rect.top, ellipticWidth, ellipticWidth)) throw(1); if(!dc->FrameRgn(rgn, &brush, 20, 20)) throw(1); if(!SetWindowRgn(*rgn, true)) throw(1); } catch(...) { MessageBox("err caught"); }
lg, phreaking
-
SetWindowRgn schickt nach dem Setzen WM_WINDOWPOSCHANGING, danach folgt WM_NCPAINT sowie WM_PAINT und damit ist Deine FrameRgn verschwunden!
Wenn Du sowas machen willst, musst Du diese Messages selber verarbeiten und in das Fenster reinzeichnen
-
Heißt das, die Nachrichten werden gar nicht verarbeitet? Wozu gibt es dann diese Funktion? Wie muss ich die Rahmen selbst zeichnen?
thx, phreaking
-
[ Dieser Beitrag wurde am 09.10.2002 um 17:16 Uhr von phreaking editiert. ]
-
Weiß dazu denn keiner eine Antwort?
lg, phreaking
-
Original erstellt von RenéG:
SetWindowRgn schickt nach dem Setzen WM_WINDOWPOSCHANGING, danach folgt WM_NCPAINT sowie WM_PAINT und damit ist Deine FrameRgn verschwunden!
Wenn Du sowas machen willst, musst Du diese Messages selber verarbeiten und in das Fenster reinzeichnenSollte die MFC dafür nicht standardmäßig schon eine Implementierung haben (CWnd::OnNcPaint)?
lg, phreaking
[ Dieser Beitrag wurde am 10.10.2002 um 21:26 Uhr von phreaking editiert. ]
-
Sollte die MFC dafür nicht standardmäßig schon eine Implementierung haben (CWnd::OnNcPaint)?
Die MFC nicht! Das ganze wird schon in den Tiefen der Windows-API erledigt und dort werden nunmal nur rechteckige Rahmen implementiert!
-
Und warum funktioniert dieses Beispiel richtig:
#include <windows.h> //--------------------------------------------------------------------------- LRESULT APIENTRY MainProc(HWND,UINT,WPARAM,LPARAM); void Init(); HINSTANCE hInst; HWND main; HRGN hRegion1,hRegion2;; int x,y,x1,y1; int APIENTRY WinMain(HINSTANCE hInstx,HINSTANCE hPrev,LPSTR line,int CmdShow) { hInst = hInstx; Init(); MSG msg; while(GetMessage(&msg,0,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void Init() { WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.lpfnWndProc = (WNDPROC) MainProc; wc.lpszClassName = "MainWnd"; wc.lpszMenuName = NULL; wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc);// register class structure // create & show the window main = CreateWindow("MainWnd","Funny Shaped Window",WS_POPUP,200,200,200,200,0,0,hInst,0); ShowWindow(main,SW_SHOW); UpdateWindow(main); //Give the region a red border FrameRgn(GetDC(main),hRegion1,CreateSolidBrush(RGB(255,0,0)),5,5); //Set the main window to the region SetWindowRgn(main,hRegion1,1); } // Main callback function LRESULT APIENTRY MainProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); break; //Create two regions and combine them using XOR to create see-thru look case WM_CREATE: { hRegion1 = CreateRoundRectRgn(0,0,200,200,40,40); hRegion2 = CreateEllipticRgn(20,20,60,60); CombineRgn(hRegion1,hRegion1,hRegion2,RGN_XOR); break; } case WM_RBUTTONUP: //Right click on the window to quit program. Because there is no //title bar we need some way of closing app SendMessage(hwnd,WM_DESTROY,0,0); break; //Also as there is no title bar we want some way of dragging/moving //the window. Use left button down to store the point, and then use mousemove //to move the form relative to that point case WM_LBUTTONDOWN: x1=LOWORD(lParam); y1=HIWORD(lParam); break; case WM_MOUSEMOVE: if(wParam==MK_LBUTTON) { RECT rec; GetWindowRect(hwnd,&rec); SetWindowPos(hwnd,0,rec.left+LOWORD(lParam)-x1,rec.top+HIWORD(lParam)-y1,0,0,SWP_NOSIZE); } break; default: return DefWindowProc(hwnd,msg,wParam,lParam); } return 0; }
Ich weiß, das ist nicht MFC, aber naja, mit der MFC müsste es doch ähnlich funktionieren. Und bei diesem Beispiel werden die entsprechenden Nachrichten ja auch nicht selbst behandelt....
so long, phreaking
-
Funktioniert das richtig?
Soviel ich sehe, nicht! Denn überdecke einfach mal das Fenster mit einem anderen, und dann mache es wieder sichtbar ... schwups is der Rahmen wech!
-
Stimmt. Aber anscheinend kann ich ja die Funktion FrameRgn auch auf mein verformtes Fenster anwenden, sonst würde bei diesem Beispiel ja auch am Anfang kein Rahmen erscheinen. Reicht es denn nicht, einen entsprechenden Aufruf von FrameRgn bei einem bestimmten WM-Event einzufügen?
thx, phreaking
-
Sagte ich ja bereits .. dazu dient WM_NCPAINT!
PS.: GetDC() verlangt auch ein ReleaseDC()