C言語で画面がおかしくなる
最近C言語でプログラムを書き始めました。
二次関数を作るスクリプトなんですが、一定時間がたつと画面がおかしくなります。
どこが問題なのか探しても見つからないので、わかる方教えてください。
WinMainの部分は省いてます
#include<windows.h>
#include<stdio.h>
#include <stdlib.h>
#include<time.h>
#define TIMER_ID 1
#define spy(num) (wy-num)
int rnd(int r);
void bset(HDC hdc, int x, int y);
LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
HDC hDC;
static int DesktopX ,DesktopY;
static HDC hdc;
static HDC Mhdc;
static HBITMAP BMPhdc;
PAINTSTRUCT paint;
RECT Rect;
LOGPEN lopnPen;
POINT CursorP, ScreenP;
char str[250];
int i;
static int wx, wy ,ky;
static double a ,b ,c ,x ,y ,n ,m ,s ,t;
switch (msg) {
case WM_DESTROY:
DeleteObject( BMPhdc );
DeleteDC( Mhdc );
PostQuitMessage(0);
return 0;
case WM_CREATE:
SetTimer(hwnd, TIMER_ID, 10, NULL);
hDC = GetDC(hwnd);
hdc = CreateCompatibleDC( hDC );
GetClientRect(GetDesktopWindow() ,&Rect);
DesktopX = Rect.right ;DesktopY = Rect.bottom;
BMPhdc = CreateCompatibleBitmap( hDC, DesktopX, DesktopY );
SelectObject( hdc, BMPhdc );
ReleaseDC( hwnd, hDC );
GetClientRect(hwnd, &Rect);
wx = Rect.right ;wy = Rect.bottom;
x = rnd(wx); y = rnd(wy);
n = rnd(wx); m = rnd(wy);
return 0;
case WM_TIMER:
ScreenP.x = LOWORD(lp);
ScreenP.y = HIWORD(lp);
GetClientRect(hwnd, &Rect);
wx = Rect.right ;wy = Rect.bottom;
if( ky == 1 ){
x = rnd(wx); y = rnd(wy);
n = rnd(wx); m = rnd(wy);
}
ClientToScreen(hwnd ,&ScreenP);
GetCursorPos(&CursorP);
s = CursorP.x-ScreenP.x;
t = wy-(CursorP.y-ScreenP.y);
InvalidateRect(hwnd, NULL, FALSE);
return 0;
case WM_RBUTTONDOWN:
ky = 1;
return 0;
case WM_RBUTTONUP:
ky = 0;
return 0;
case WM_PAINT:
Mhdc = BeginPaint(hwnd, &paint);
SelectObject(hdc , CreateSolidBrush(RGB(255,255,255)));
lopnPen.lopnStyle = PS_NULL;
SelectObject(hdc , CreatePenIndirect(&lopnPen));
Rectangle(hdc , 0 , 0 , wx+1 , wy+1);
SelectObject(hdc , CreateSolidBrush(RGB(255,0,0)));
if ((s-n) != 0 && (n-x) != 0 && (s-x) != 0){
a = ((t-m)/(s-n) - (m-y)/(n-x)) / (s-x);
b = (m-y)/(n-x) - a*(n+x);
c = y - a*x*x -b*x;
}
bset(hdc, x,spy(y));
bset(hdc, n,spy(m));
bset(hdc, s,spy(t));
lopnPen.lopnStyle = PS_SOLID;
lopnPen.lopnColor = RGB(0,0,255);
SelectObject(hdc , CreatePenIndirect(&lopnPen));
MoveToEx(hdc , -1 , spy( a + b - c) , NULL);
for(i = 0 ; i <= wx ;i++){
LineTo(hdc , i , spy( a*i*i - b*i - c));
}
BitBlt(Mhdc, 0, 0, DesktopX, DesktopY, hdc, 0, 0, SRCCOPY );
EndPaint(hwnd, &paint);
return 0;
}
return DefWindowProc(hwnd , msg , wp , lp);
}
int rnd(int r){
static int flag;
if (flag == 0) {
srand((unsigned int)time(NULL));
flag = 1;
}
return (int)(rand()*(r+1.0)/(1.0+RAND_MAX));
}
void bset(HDC hdc, int x, int y){
static LOGPEN lopnPen;
lopnPen.lopnStyle = PS_NULL;
SelectObject(hdc , CreatePenIndirect(&lopnPen));
Rectangle(hdc , x-3 , y-3 , x+3 , y+3);
return;
}
お礼
ありがとうございました。 おかげで、ほとんど、できあがりました。感謝です。 原因は、見ての通り、EnhMetaFile APIと普通のMetaFile APIの混在、 GetDataの描画に、BitBltでなくPlayEnhMetaFile() を使ったため BitBlt時、転送元DCが無効になるケースがあったため でした。