Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++ и WinAPI

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
Игорь с++
437 / 460 / 16
Регистрация: 26.01.2011
Сообщений: 2,033
#1

Виртуальный контекст - C++ WinAPI

16.05.2012, 18:21. Просмотров 1856. Ответов 15
Метки нет (Все метки)

Господа я так понимаю это должно быть виртуальное окно?Вопрос как сделать виртульное окно и то , что мы туда нарисум перенести на наше окно. хочу понять как вывести фон+картинку без моргание,но вот , что такое виртуальный контекст и как с ним работать,что то не пойму + как из виртуального контекста переместить изображение не как не пойму.Вот допустим такой ког -
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <windows.h>
 
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";
HINSTANCE hInst;
void DrawBitmap(HDC hDC, int x, int y, HBITMAP hBitmap);
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)
 
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
 
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);
 
    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 
    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
 
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           600,                 /* The programs width */
           600,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
 
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);
 
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }
 
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}
 
 
/*  This function is called by the Windows function DispatchMessage()  */
 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        static HBITMAP hBitmap;
        static HBITMAP hBitmap2;
        HDC hdc;
        PAINTSTRUCT ps;
static int x=0;
RECT rect;//rect.bottom=0;rect.left=0;rect.right=600;rect.top=60;
    switch (message)                  /* handle the messages */
    {
case WM_CREATE:
hBitmap = (HBITMAP)LoadImage(NULL, "fon.bmp", IMAGE_BITMAP, 600, 600, LR_LOADFROMFILE);
hBitmap2 = (HBITMAP)LoadImage(NULL, "kar.bmp", IMAGE_BITMAP, 60, 60, LR_LOADFROMFILE);
SetTimer(hwnd,1,0,NULL);
                 break;
case WM_TIMER:
     x++;
     rect.bottom=0;rect.left=x;rect.right=x+60;rect.top=60;
     InvalidateRect(hwnd,&rect,FALSE);
     break;
        case WM_PAINT:
                hdc=BeginPaint(hwnd,&ps);
                DrawBitmap(hdc, 0,0,hBitmap);
                DrawBitmap(hdc, x,0,hBitmap2);
                EndPaint(hwnd,&ps);
                break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
 
    return 0;
}
void DrawBitmap(HDC hDC, int x, int y, HBITMAP hBitmap)
{
        HBITMAP hbm, hOldbm;
        HDC hMemDC;
        BITMAP bm;
        POINT ptSize, ptOrg;
 
        // ÑîçäГ*ГҐГ¬ ГЄГ®Г*ГІГҐГЄГ±ГІ ГЇГ*ìÿòè, ñîâìåñòèìûé
        // Г± ГЄГ®Г*òåêñòîì îòîáðГ*æåГ*ГЁГї
        hMemDC = CreateCompatibleDC(hDC);
 
        // ÂûáèðГ*ГҐГ¬ èçîáðГ*æåГ*ГЁГҐ bitmap Гў ГЄГ®Г*ГІГҐГЄГ±ГІ ГЇГ*ìÿòè
        hOldbm = (HBITMAP)SelectObject(hMemDC, hBitmap);
 
        // Åñëè Г*ГҐ áûëî îøèáîê, ïðîäîëæГ*ГҐГ¬ Г°Г*áîòó
        if (hOldbm)
        {
                // Äëÿ ГЄГ®Г*ГІГҐГЄГ±ГІГ* ГЇГ*ìÿòè ГіГ±ГІГ*Г*Г*âëèâГ*ГҐГ¬ òîò æå
                // ðåæèì îòîáðГ*æåГ*ГЁГї, Г·ГІГ® èñïîëüçóåòñÿ Гў
                // ГЄГ®Г*ГІГҐГЄГ±ГІГҐ îòîáðГ*æåГ*ГЁГї
                SetMapMode(hMemDC, GetMapMode(hDC));
 
                // Îïðåäåëÿåì Г°Г*çìåðû èçîáðГ*æåГ*ГЁГї
                GetObject(hBitmap, sizeof(BITMAP), (LPSTR) &bm);
 
                ptSize.x = bm.bmWidth;  // øèðèГ*Г*
                ptSize.y = bm.bmHeight; // âûñîòГ*
 
                // ÏðåîáðГ*çóåì êîîðäèГ*Г*ГІГ» óñòðîéñòâГ* Гў ëîãè÷åñêèå
                // äëÿ óñòðîéñòâГ* âûâîäГ*
                DPtoLP(hDC, &ptSize, 1);
 
                ptOrg.x = 0;
                ptOrg.y = 0;
 
                // ÏðåîáðГ*çóåì êîîðäèГ*Г*ГІГ» óñòðîéñòâГ* Гў ëîãè÷åñêèå
                // äëÿ ГЄГ®Г*ГІГҐГЄГ±ГІГ* ГЇГ*ìÿòè
                DPtoLP(hMemDC, &ptOrg, 1);
 
                // ГђГЁГ±ГіГҐГ¬ èçîáðГ*æåГ*ГЁГҐ bitmap
                BitBlt(hDC, x, y, ptSize.x, ptSize.y,
                        hMemDC, ptOrg.x, ptOrg.y, SRCCOPY);
 
                // ÂîññòГ*Г*Г*âëèâГ*ГҐГ¬ ГЄГ®Г*ГІГҐГЄГ±ГІ ГЇГ*ìÿòè
                SelectObject(hMemDC, hOldbm);
        }
 
        // ÓäГ*ëÿåì ГЄГ®Г*ГІГҐГЄГ±ГІ ГЇГ*ìÿòè
        DeleteDC(hMemDC);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.05.2012, 18:21
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Виртуальный контекст (C++ WinAPI):

Контекст принтера - C++ WinAPI
Есть имя принтера. Как получить DC? Так получаю ноль. HDC hdc = CreateDC(0, (LPCWSTR)&quot;Canon PIXMA iP2000&quot;, 0,0);

Выбор шрифтов в контекст - C++ WinAPI
В папке Windows\Fonts лежит куча разных шрифтов и я хочу использовать какой-нибудь из них в своей программе. Но для этого нужно выбрать...

Как получить контекст чужого процесса ? - C++ WinAPI
Пробую получить контекст чужого процесса на х64 системе. ...

Как обрезать картинку выбраную в контекст устройства? - C++ WinAPI
Приветствую. Разбираюсь с GDI. Возник вопрос. Подскажите, как обрезать картинку выбраную в контекст устройства? поясню: создаю контекст...

WinApi C++ не знаю, как подключить контекст принтера - C++ WinAPI
Не знаю, как подключить контекст принтера. Использую Visual Studio 2008. Нужно подключить контекст принтера и с помощью функции TextOut...

GDI. Вывод bmp через промежуточный совместимый контекст - C++ WinAPI
Почему не выводит картинку код типа: HDC hdc = GetDC(hWnd); HDC hMemDC1 = CreateCompatibleDC(hdc); HDC hMemDC2 =...

15
Игорь с++
437 / 460 / 16
Регистрация: 26.01.2011
Сообщений: 2,033
02.06.2012, 23:17  [ТС] #2
господа вот пытаюсь сделать при помощи двойной буферизации но не получается есть моргание-
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
case WM_TIMER:
                      x++;
                 InvalidateRect(hwnd,0,TRUE);
                      break;
case WM_PAINT:
 
                hdcMem=BeginPaint(hwnd,&ps);
hdcMem=CreateCompatibleDC(hdc);
hBitmapMEM = (HBITMAP)SelectObject(hdcMem, hBitmap);
 
                DrawBitmap(hdcMem, x,y,hBitmap);
EndPaint(hwnd,&ps);
 
                hdc=BeginPaint(hwnd,&ps);
SelectObject(hdc,hBitmap);
                DrawBitmap(hdc, x,y,hBitmapMEM);
                EndPaint(hwnd,&ps);
 
                break;
вообще не чего не появляется,если убрать строку - hdcMem=CreateCompatibleDC(hdc); то появляется но моргает , и вообще мне кажется , что я в корне как то не так делаю двойную буферизацию.
я вот , что не понимаю - как я могу скопировать изображение в hdc памяти , затем как из памяти отресовать на окно ?Помоги те кто знает , а то всё моргает !!!
0
-=ЮрА=-
Заблокирован
Автор FAQ
07.06.2012, 21:04 #3
Игорь с++, зачем тебе перерисовка всего окна по таймеру?Может по таймеру лучше контролы перерисовывать/переинциализировать инфу в них?
0
Игорь с++
437 / 460 / 16
Регистрация: 26.01.2011
Сообщений: 2,033
07.06.2012, 21:29  [ТС] #4
пардон не понял !!!
0
-=ЮрА=-
Заблокирован
Автор FAQ
07.06.2012, 21:59 #5
Зачем ты рисуешь битмап каждый тик таймера. Нарисуй его и перерисоввывай лишь по WM_SIZE а здесь
Цитата Сообщение от Игорь с++ Посмотреть сообщение
InvalidateRect(hwnd,0,TRUE);
вместо InvalidateRect вбей SetDlgItemInt(Text) вобщем выдачу показателей в окно. Я так понимаю у тебя ежесекундная статистика должна идти
1
Dimazzzzzz
588 / 95 / 2
Регистрация: 24.01.2009
Сообщений: 379
08.06.2012, 20:01 #6
Чтобы не было моргания при использовании InvalidateRect (), нужно чтобы третий параметр был равен false. Кроме этого второй параметр должен содержать прямоугольник, который передается в структуру PAINTSTRUCT при вызове BeginPaint (). Вот тогда и нужно делать с этим прямоугольником всё что нужно.

Лучше всего не рисовать при возникновении WM_PAINT, а просто копировать с контекста в памяти. Вот мой старый пример. Построение обработчика таким образом еще полезно потому, что при приеме сообщения WM_PAINT посланного не вами, а системой, так же будет просто копирование с использованием прямоугольника, приходящего в PAINTSTRUCT.
0
Игорь с++
437 / 460 / 16
Регистрация: 26.01.2011
Сообщений: 2,033
08.06.2012, 22:44  [ТС] #7
Dimazzzzzz, это я уже понял , как наложить картинку на контекст и потом от туда её перекинуть на окно ?
0
Dimazzzzzz
588 / 95 / 2
Регистрация: 24.01.2009
Сообщений: 379
08.06.2012, 22:54 #8
Игорь с++, ну так в примере всё есть со всеми комментами. Там ничего лишнего, только основное для создания этого механизма. Единственное там я использовал второй поток для рисования, а не таймер, хотя принципиальной разницы тут нет.
1
Игорь с++
437 / 460 / 16
Регистрация: 26.01.2011
Сообщений: 2,033
14.06.2012, 18:50  [ТС] #9
Господа со всем разобрался , но есть один вопрос который я так и не сумел решить
Суть проблеммы -
1) вот так я определил клиентскую область
C++
1
hdc = GetDC(hwnd);
2)создал виртуальный контекст -
C++
1
memBit = CreateCompatibleDC(hdc);
3)создал виртуальный битмап,т.к. я понял , что контекст сам не хранит изображения-
C++
1
bmpMem = CreateCompatibleBitmap (hdc, 600, 400);
4)Теперь самое основное - как мне своё изображение hBitmap скопировать на виртуальный битмап
5)и копирование на наше окно я так пологаю будет выглядить следующем образом -
C++
1
BitBlt(hdc,x,y,80,80,memBit,0,0,SRCCOPY);
Вообщем вопрос в том как в виртуальном контексте , на виртульном битмапе нарисовать свой битмап да ещё и в определённой точки грубо говоря 100,100 .
Заранее буду очень благодарен за ответ , всю голову себе уже сломал , но понять НЕ МОГУ !!!

Добавлено через 24 минуты
Вот я пытаюсь нарисовать два изображения на виртуальный битмап , но не чго не выходит , показывает то , что рисуем последнее -
C++
1
2
3
4
5
bmpMem = (HBITMAP)SelectObject (memBit, hBitmap[1]);
BitBlt(memBit,0,0,600,400,memBit,0,0,SRCCOPY);
 
bmpMem = (HBITMAP)SelectObject (memBit, hBitmap[0]);
BitBlt(memBit,x,y,80,80,memBit,0,0,SRCCOPY);
0
-=ЮрА=-
14.06.2012, 21:06
  #10

Не по теме:

Цитата Сообщение от Игорь с++ Посмотреть сообщение
Вот я пытаюсь нарисовать два изображения на виртуальный битмап , но не чго не выходит , показывает то , что рисуем последнее -
- ну понятное дело что последниее, так думаю битмапы не смешать, попробуй просумировать битмапы а в контекст вывести уже "суммарную колбасу"

0
Игорь с++
437 / 460 / 16
Регистрация: 26.01.2011
Сообщений: 2,033
14.06.2012, 22:13  [ТС] #11
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
так думаю битмапы не смешать
почему?Я же могу нарисовать один битмап на другой , в своём окне !!!
0
-=ЮрА=-
14.06.2012, 22:16
  #12

Не по теме:

Цитата Сообщение от Игорь с++ Посмотреть сообщение
Я же могу нарисовать один битмап на другой , в своём окне !!!
- без прозрачности не можешь, хотябы альфа бленд какой сделай. Ну лан, не буду мешать твоим творческим поискам...

0
Игорь с++
437 / 460 / 16
Регистрация: 26.01.2011
Сообщений: 2,033
14.06.2012, 22:36  [ТС] #13
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
без прозрачности не можешь
Здрасти приехали !!! Загружаешь один битмап , затем другой , в паинти рисуеш первый битмап , и другой .
0
Vlad1slav
21 / 21 / 5
Регистрация: 16.09.2009
Сообщений: 111
15.06.2012, 02:23 #14
Цитата Сообщение от Игорь с++ Посмотреть сообщение
Вообщем вопрос в том как в виртуальном контексте , на виртульном битмапе нарисовать свой битмап да ещё и в определённой точки грубо говоря 100,100 .
Заранее буду очень благодарен за ответ , всю голову себе уже сломал , но понять НЕ МОГУ !!!

Добавлено через 24 минуты
Вот я пытаюсь нарисовать два изображения на виртуальный битмап , но не чго не выходит , показывает то , что рисуем последнее -
C++
1
2
3
4
5
bmpMem = (HBITMAP)SelectObject (memBit, hBitmap[1]);
BitBlt(memBit,0,0,600,400,memBit,0,0,SRCCOPY);
 
bmpMem = (HBITMAP)SelectObject (memBit, hBitmap[0]);
BitBlt(memBit,x,y,80,80,memBit,0,0,SRCCOPY);
Когда-то двое суток просидел, чтобы полностью разобраться как работать с bitmapami.
В общем, думаю Вам будет полезен мой код) Последний конструктор накладывает 2 картинку на 1, как я понял, это то что Вам надо).

Image.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#pragma once
 
class Image {
 
private:
    LPVOID                  lpBuffer;
    LPBITMAPINFO    lpBmpInfo;
 
    void                            ConvertTo32();
    void                            InitInfo();
    void                            GetDIBitsFromMemDC(HDC hMemDC, HBITMAP hBmp, int Height);
 
public:
    Image(const wchar_t* fname);
    Image(HWND hwnd, int x, int y, int cx, int cy);
    Image(Image* img1, Image* img2);
    Image(int cx, Image* img1, int x1, int y1, int cy1, Image* img2, int x2, int y2, int cy2);
    Image(Image* img1, Image* img2, int srcx, int srcy, int x, int y, int cx, int cy);
    ~Image();
 
    Image*                      SaveBmp(const wchar_t* fname);
    void                            Paint(HDC hdc); 
 
    LPVOID                  GetBuffer() {   return  lpBuffer;       }
    LPBITMAPINFO    GetInfo()       {   return  lpBmpInfo;  }
 
    static bool             Compare(Image* img1, Image* img2);
 
    void MakeDC(HDC hdc, HBITMAP& hBmp, HDC& hMemDC);
    static void UnMakeDC(HBITMAP hBmp, HDC hMemDC);
};
В stdafx.h добавил:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <windows.h>
 
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
 
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <stdio.h>
#include <mmsystem.h>
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// Image.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Image.h"
 
//Открыть картинку с диска
Image::Image(const wchar_t* fname) {
    FILE* f;
    LPBITMAPFILEHEADER lpbFileh;
    int infosize;
 
    f=_wfopen(fname, L"rb");
    lpbFileh=new BITMAPFILEHEADER;
    fread(lpbFileh, sizeof(BITMAPFILEHEADER), 1, f);
    infosize=lpbFileh->bfOffBits-sizeof(BITMAPFILEHEADER);
    lpBmpInfo=(LPBITMAPINFO)malloc(infosize);
    fread(lpBmpInfo, infosize, 1, f);
    lpBuffer=malloc(lpBmpInfo->bmiHeader.biSizeImage);
    fread(lpBuffer, lpBmpInfo->bmiHeader.biSizeImage, 1, f);
    fclose(f);
    if (lpBmpInfo->bmiHeader.biBitCount!=32) {
        ConvertTo32();
        SaveBmp(fname);
    }
}
 
//Перевести картинку из 24 в 32 разрядную
void Image::ConvertTo32() {
    int cy=lpBmpInfo->bmiHeader.biHeight;
    HDC hdc=GetDC(NULL);
    HDC hMemDC;
    HBITMAP hBmp;
    MakeDC(hdc, hBmp, hMemDC);
    ReleaseDC(NULL, hdc);
    
    delete lpBuffer;
    delete lpBmpInfo;
 
    InitInfo();
    GetDIBitsFromMemDC(hMemDC, hBmp, cy);
 
    for (int i=0, size=lpBmpInfo->bmiHeader.biSizeImage; i<size; i+=4) 
        *((unsigned char*)lpBuffer+i+3)=(unsigned char)0xFF;
 
    UnMakeDC(hBmp, hMemDC);
}
 
//Сравнить 2 картинки. Те пиксели что равны будут FFFFFF, что не равны будут браться из 2 картинки. Функция возвращает результирующую картинку.
Image::Image(Image* img1, Image* img2) {
    LPBITMAPINFO info1=img1->GetInfo();
    LPBITMAPINFO info2=img2->GetInfo();
    if (info1->bmiHeader.biSizeImage!=info2->bmiHeader.biSizeImage) 
        exit(1);
 
    lpBmpInfo=(LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD));
    memcpy(lpBmpInfo, info2, sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD));
 
    lpBuffer=malloc(lpBmpInfo->bmiHeader.biSizeImage); 
    unsigned int* lpBuffer1=(unsigned int*)img1->GetBuffer();
    unsigned int* lpBuffer2=(unsigned int*)img2->GetBuffer();
    
    for (int i=0, size=lpBmpInfo->bmiHeader.biSizeImage/4; i<size; i++) {
        if (*(lpBuffer1+i)==*(lpBuffer2+i))
            *((unsigned int*)lpBuffer+i)=0xFFFFFFFF;
        else 
            *((unsigned int*)lpBuffer+i)=*(lpBuffer2+i);
    }
}
 
//Склеивает 2 картинки вертикально. 
//cx-ширина склеивания
//(x1|y1)-координаты левого верхнего угла 1 картинки
//(x2|y2)-координаты левого верхнего угла 2 картинки
//cy1(cy2)-высота 1(2) части картинки, cy=cy1+cy2, где cy=высота склеиваемой картинки
Image::Image(int cx, Image* img1, int x1, int y1, int cy1, Image* img2, int x2, int y2, int cy2) {
    int cy=cy1+cy2;
    LPBITMAPINFO info1=img1->GetInfo();
    LPBITMAPINFO info2=img2->GetInfo();
    LPVOID lpBuffer1=img1->GetBuffer();
    LPVOID lpBuffer2=img2->GetBuffer();
 
    lpBmpInfo=(LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD));
    memcpy(lpBmpInfo, info1, sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD));
    lpBmpInfo->bmiHeader.biWidth=cx;
    lpBmpInfo->bmiHeader.biHeight=cy;
    lpBmpInfo->bmiHeader.biSizeImage=cx*cy*4;
 
    lpBuffer=malloc(lpBmpInfo->bmiHeader.biSizeImage);
    int* buf=(int*)lpBuffer;
    int* p=(int*)lpBuffer2+info2->bmiHeader.biWidth*(info2->bmiHeader.biHeight-y2-cy2)+x2;
    for (int i=0; i<cy2; i++) 
        memcpy(buf+i*cx, p+info2->bmiHeader.biWidth*i, cx*4);
    
    buf+=cx*cy2;
    p=(int*)lpBuffer1+info1->bmiHeader.biWidth*(info1->bmiHeader.biHeight-y1-cy1)+x1;
    for (int i=0; i<cy1; i++) 
        memcpy(buf+i*cx, p+info1->bmiHeader.biWidth*i, cx*4);
}
 
//Делаем скрин части окна
Image::Image(HWND hwnd, int x, int y, int cx, int cy) {
    HDC hdc=GetDC(hwnd);
    if (!hdc)
        exit(2);
 
    HBITMAP hBmp=CreateCompatibleBitmap(hdc, cx, cy);
    HDC hMemDC=CreateCompatibleDC(hdc);
    SelectObject(hMemDC, hBmp);
 
    BitBlt(hMemDC, 0, 0, cx, cy, hdc, x, y,  SRCCOPY);
 
    InitInfo();
    GetDIBitsFromMemDC(hMemDC, hBmp, cy);
 
    ReleaseDC(hwnd, hdc);
    UnMakeDC(hBmp, hMemDC);
}
 
//Удаляем картинку
Image::~Image() {
    delete lpBuffer;
    delete lpBmpInfo;
}
 
//Сохраняем картинку на диск
Image* Image::SaveBmp(const wchar_t* fname) {
    LPBITMAPFILEHEADER lpbmpfh;
    FILE* f;
 
    lpbmpfh=new BITMAPFILEHEADER;
    lpbmpfh->bfType=0x4d42;
    lpbmpfh->bfReserved1=lpbmpfh->bfReserved2=0;
    lpbmpfh->bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+3*sizeof(RGBQUAD);
    lpbmpfh->bfSize=lpbmpfh->bfOffBits+lpBmpInfo->bmiHeader.biSizeImage;
 
    f=_wfopen(fname, L"wb");
 
    fwrite(lpbmpfh, sizeof(BITMAPFILEHEADER), 1, f);
    fwrite(lpBmpInfo, sizeof(BITMAPINFOHEADER)+3*sizeof(RGBQUAD), 1, f);
    fwrite(lpBuffer, lpBmpInfo->bmiHeader.biSizeImage, 1, f);
    
    fclose(f);
 
    return this;
}
 
//Выводим картинку на экран
void Image::Paint(HDC hdc) {
    HDC hMemDC;
    HBITMAP hBmp;
    MakeDC(hdc, hBmp, hMemDC);
    BitBlt(hdc, 0, 0, lpBmpInfo->bmiHeader.biWidth, lpBmpInfo->bmiHeader.biHeight, hMemDC, 0, 0, SRCCOPY);
    UnMakeDC(hBmp, hMemDC);
}
 
//Сравниваем 2 картинки
bool Image::Compare(Image* img1, Image* img2) {
    int size=img1->GetInfo()->bmiHeader.biSizeImage;
    if (size!=img2->GetInfo()->bmiHeader.biSizeImage) 
        return false;
    return !memcmp(img1->GetBuffer(), img2->GetBuffer(), size);
}
 
//Накладывает вторую картинку на первую(ВНИМАНИЕ: предпологается что 2 картинка меньше 1 и при наложении не вылазит за пределы!!!)
//srcx, srcy-координаты точки на 2 картинке, с которой начинается прорисовка
//x, y-координаты точки на 1 катинке, с которой начинается накладывание второй картинки
//cx, cy-накладываемая ширина и высота второй картинкиы.
Image::Image(Image* img1, Image* img2, int srcx, int srcy, int x, int y, int cx, int cy) {
    HDC hdc=GetDC(NULL);
    HDC hMemDC1, hMemDC2;
    HBITMAP hBmp1, hBmp2;
 
    img1->MakeDC(hdc, hBmp1, hMemDC1);
    img2->MakeDC(hdc, hBmp2, hMemDC2);
 
    lpBmpInfo=img1->GetInfo();
    
    HDC hMemDC=CreateCompatibleDC(hMemDC2);
    HBITMAP hBmp=CreateCompatibleBitmap(hMemDC2, lpBmpInfo->bmiHeader.biWidth, lpBmpInfo->bmiHeader.biHeight);
    SelectObject(hMemDC, hBmp);
 
    BitBlt(hMemDC, 0, 0, lpBmpInfo->bmiHeader.biWidth, lpBmpInfo->bmiHeader.biHeight, hMemDC1, 0, 0,  SRCCOPY);
    BitBlt(hMemDC, x, y, cx, cy, hMemDC2, srcx, srcy,  SRCCOPY);
 
    InitInfo();
    GetDIBitsFromMemDC(hMemDC, hBmp, cy);
 
    ReleaseDC(NULL, hdc);
    UnMakeDC(hBmp1, hMemDC1);
    UnMakeDC(hBmp2, hMemDC2);
    UnMakeDC(hBmp, hMemDC);
}
 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////      private-функции c частовстречаемыми кусками кода !          ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void Image::MakeDC(HDC hdc, HBITMAP& hBmp, HDC& hMemDC) {
    hMemDC=CreateCompatibleDC(hdc);
    hBmp=CreateCompatibleBitmap(hdc, lpBmpInfo->bmiHeader.biWidth, lpBmpInfo->bmiHeader.biHeight);
    SetDIBits(hMemDC, hBmp, 0, lpBmpInfo->bmiHeader.biHeight, lpBuffer, lpBmpInfo, DIB_RGB_COLORS);
    SelectObject(hMemDC, hBmp);
}
 
void Image::UnMakeDC(HBITMAP hBmp, HDC hMemDC) {
    DeleteObject(hBmp);
    DeleteDC(hMemDC);
}
 
void Image::InitInfo() {
    lpBmpInfo=(LPBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD));
    ZeroMemory(&lpBmpInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
    lpBmpInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
}
 
void Image::GetDIBitsFromMemDC(HDC hMemDC, HBITMAP hBmp, int Height) {
    GetDIBits(hMemDC, hBmp, 0, Height, NULL, lpBmpInfo, DIB_RGB_COLORS);
    lpBuffer=malloc(lpBmpInfo->bmiHeader.biSizeImage);
    GetDIBits(hMemDC, hBmp, 0, lpBmpInfo->bmiHeader.biHeight, lpBuffer, lpBmpInfo, DIB_RGB_COLORS);
}
1
Игорь с++
437 / 460 / 16
Регистрация: 26.01.2011
Сообщений: 2,033
15.06.2012, 09:06  [ТС] #15
Спасибо более конкретно посматрю код вечером , и ещё не могли бы принцип подсказать ? Да и ещё мне их полностью склеивать не надо , т.к. это просто передвижение обьекта на экране , а вирт. контекст ,что бы не было морганий .
0
15.06.2012, 09:06
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.06.2012, 09:06
Привет! Вот еще темы с ответами:

Как сделать виртуальный диск? - C++ WinAPI
Как можно создать виртуальный диск из файла-образа? Например как в PGPdisk. Если для этого нужен драйвер, то где можно почитать про это?

Виртуальный код клавмши точка - C++ WinAPI
У меня функция winapi запрашивает виртуальный код клавиши, типа VK_KEYUP, VK_DELETE и тп. А какой код у точки - &quot;.&quot; ?

Виртуальный код кнопки включения электропитания - C++ WinAPI
Вот на системном блоке есть такая большая кнопка, которая включает компьютер, какой у этой кнопки виртуальный код(типа как у клавиши Enter...

Виртуальный замок - C++
Доброе утро! Возникла такая проблема. Допустим, я хочу запретить наследоваться от своего класса другим классам и получить ошибку...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.