Как сделать непрямоугольное окно? - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Я видел приложения, окна которых имеют какую-то фантастическую форму. Вопрос: как сделать окно произвольной формы в Windows 7 на Си?

Решение задачи: «Как сделать непрямоугольное окно?»

textual
Листинг программы
#include <windows.h>
#include <math.h>
#include <stdio.h>
#ifndef M_PI
#define M_PI  3.1415926535897932384626433832795
#endif
static LRESULT CALLBACK myWndProc(HWND, UINT, WPARAM, LPARAM);
static HWND showDialog(HINSTANCE, LPCTSTR);
 
//диалог в форме звезды
BOOL setWindowStar(HWND hwnd, int cnt){
        int    i, angle, ox, oy, rx, ry, r1, r2;
        double t1, t2;
        HRGN   rgn;
        RECT   rc;
        DWORD  err;
        POINT* dots;
 
        if(cnt < 3)
                return FALSE;
        dots = (POINT*)HeapAlloc(GetProcessHeap(), 0, (cnt * 2) * sizeof(POINT));
        if(dots == NULL)
                return FALSE;
        
        GetClientRect(hwnd, &rc);
        ox    = rc.right  / 2;
        oy    = rc.bottom / 2;
        rx    = ox - 20;
        ry    = oy - 20;
        r1    = rx / 3;
        r2    = ry / 3;
        angle = 360 / cnt;
        for(i = 0; i < cnt; ++i){
                t1 = (double)(i * angle) * M_PI / 180.0;
                t2 = (double)(i * angle + angle / 2) * M_PI / 180.0;
                dots[i*2+0].x = ox + rx * sin(t1);
                dots[i*2+0].y = oy + ry * cos(t1);
                dots[i*2+1].x = ox + r1 * sin(t2);
                dots[i*2+1].y = oy + r2 * cos(t2);                
        }
        
        rgn = CreatePolygonRgn(dots, cnt * 2, WINDING);
        err = GetLastError();
        HeapFree(GetProcessHeap(), 0, dots);
        if(rgn != NULL){
                SetWindowRgn(hwnd, rgn, TRUE);
                DeleteObject(rgn);
                return TRUE;
        }
        SetLastError(err);
        return FALSE;
}
 
 
int main(void){
        int  i;
        MSG  msg;
        HWND hwnd = showDialog((HINSTANCE)GetModuleHandle(NULL), TEXT("Звезда"));
        if(hwnd == NULL){
                fprintf(stderr, "code error: %;u\n", GetLastError());
                return 1;
        }
        
        //зададим форму диалога в виде звезды
        for(i = 4; i <= 24; i += 4){
                setWindowStar(hwnd, i);
                Sleep(1200UL);
        }
  
    while(GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    } 
        return 0;
}
 
 
static HWND showDialog(HINSTANCE hInst, LPCTSTR caption){
    HWND    hwnd;
    LPCTSTR cls = TEXT("StarDlg");
    WNDCLASSEX wcls = {0};
    wcls.cbSize        = sizeof(WNDCLASSEX);
    wcls.lpfnWndProc   = (WNDPROC)myWndProc;
    wcls.hInstance     = hInst;
    wcls.hIcon         = NULL;
    wcls.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wcls.lpszClassName = cls;
    wcls.hIconSm       = NULL;
    wcls.hbrBackground = CreateHatchBrush(HS_CROSS, RGB(0, 0, 0xFF));
    if(! RegisterClassEx(&wcls))
        return NULL;
 
    hwnd = CreateWindowEx(0, cls, caption, WS_OVERLAPPEDWINDOW, 
                              CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
    if(hwnd == NULL) {
        UnregisterClass(cls, hInst);
        return NULL;
    }
    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);
        return hwnd;
}
 
static LRESULT CALLBACK myWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
        switch(msg){
        case WM_RBUTTONDOWN:
        case WM_LBUTTONDOWN:
        case WM_DESTROY:
                PostQuitMessage(0);
                break;
        default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
}

Оцени полезность:

11   голосов , оценка 4 из 5
Похожие ответы