普段お世話になっています、南山まさかずと申す
ものです。
今回は、Dxライブラリのバグ? と言うか異常現象
らしきものを発見したので、報告させていただきま
す。
まず最初に僕の使用している環境ですが、
VC2008EEを使用しております。ライブラリのバージ
ョンは3.06cです。
次に、報告する異常現象(他に形容の使用がありま
せん)ですが、題名にもあるとおり、SetWindowSize
関数を用いたときに起こります。具体的には、ウィ
ンドウのサイズを規定のものから変えたときに起こ
ります。
具体例として次のソースを載せておきます(汚い
ソースコードですが、とりあえず実行した結果をコ
メントの内容と比べていただければ分かるかと思い
ます)。
/*
Test.cpp
このプログラムを実行すると、一見正しい結果になっているように見えますが
よくソースコードと比べると時計の高さとウィンドウの高さの比がおかしなことになっています
*/
#include<fstream>
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include"DxLib.h"
using namespace std;
typedef basic_string<TCHAR> Tstring;
typedef basic_fstream<TCHAR> Tfstream;
typedef long long int LLint;
const int WINWIDTH=800; //ここの数字を640以外にすると時計のサイズ比がおかしくなる
const int WINHIGH=WINWIDTH*3/4;
const int FONTSIZE=30;
const int FONTWIDTH=0;
const long double PI_NUMBER=3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679L;
struct WatchData{
public:
DATEDATA Time;
Tstring Job;
bool operator==(const WatchData &data)const{
return
(Time.Year==data.Time.Year)&&
(Time.Mon==data.Time.Mon)&&
(Time.Day==data.Time.Day)&&
(Time.Hour==data.Time.Hour)&&
(Time.Min==data.Time.Min)&&
(Time.Sec==data.Time.Sec)&&
(Job==data.Job);
}
};
int EndNum=0;
int DrawWatch(DATEDATA &data){ //時計のサイズはウィンドウの高さの半分のはず
if(DrawBox(0,0,WINHIGH/2,WINHIGH/2,GetColor(127,127,127),TRUE)){
throw logic_error("時計の描画に失敗しました");
}int h=data.Hour,m=data.Min,s=data.Sec;
int x=WINHIGH/4;
if(DrawCircle(x,x,x,GetColor(255,255,255),TRUE)){
throw logic_error("時計の描画に失敗しました");
}if(DrawCircle(x,x,x/10,GetColor(0,0,0),TRUE)){
throw logic_error("時計の描画に失敗しました");
}if(DrawCircle(x,x,x,GetColor(0,0,0),FALSE)){
throw logic_error("時計の描画に失敗しました");
}for(unsigned int i=0;i<60;i++){
if(i%5){
if(DrawLine(static_cast<int>(x*(1+(sin(i*PI_NUMBER/30.0L)))),static_cast<int>(x*(1-(cos(i*PI_NUMBER/30.0L)))),static_cast<int>(x*(1+(0.95L*sin(i*PI_NUMBER/30.0L)))),static_cast<int>(x*(1-(0.95L*cos(i*PI_NUMBER/30.0L)))),GetColor(0,0,0))){
throw logic_error("時計の描画に失敗しました");
}
}else{
if(DrawLine(static_cast<int>(x*(1+(sin(i*PI_NUMBER/30.0L)))),static_cast<int>(x*(1-(cos(i*PI_NUMBER/30.0L)))),static_cast<int>(x*(1+(0.9L*sin(i*PI_NUMBER/30.0L)))),static_cast<int>(x*(1-(0.9L*cos(i*PI_NUMBER/30.0L)))),GetColor(0,0,0))){
throw logic_error("時計の描画に失敗しました");
}
}
}long double th=s/60.0L;
int thint=static_cast<int>(th);
if(DrawLine(x,x,static_cast<int>(x*(1+(0.8L*sin(2.0L*PI_NUMBER*(th))))),static_cast<int>(x*(1-(0.8L*cos(2.0L*PI_NUMBER*(th))))),GetColor(0,0,0))){
throw logic_error("時計の描画に失敗しました");
}th/=60.0L;
th+=m/60.0L;
if(DrawLine(x,x,static_cast<int>(x*(1+(0.7L*sin(2.0L*PI_NUMBER*(th))))),static_cast<int>(x*(1-(0.7L*cos(2.0L*PI_NUMBER*(th))))),GetColor(0,0,0))){
throw logic_error("時計の描画に失敗しました");
}th/=12.0L;
th+=h/12.0L;
if(DrawLine(x,x,static_cast<int>(x*(1+(0.9L*sin(2.0L*PI_NUMBER*(th))))),static_cast<int>(x*(1-(0.9L*cos(2.0L*PI_NUMBER*(th))))),GetColor(0,0,0))){
throw logic_error("時計の描画に失敗しました");
}TCHAR *str=_T("%04d/%02d/%02d %02d:%02d:%02d");
int width=GetDrawFormatStringWidth(str,data.Year,data.Mon,data.Day,data.Hour,data.Min,data.Sec);
if(DrawBox(0,2*x,width,2*x+FONTSIZE,GetColor(0,0,0),TRUE)){
throw logic_error("時刻の描画に失敗しました");
}if(DrawFormatString(0,2*x,GetColor(255,255,255),str,data.Year,data.Mon,data.Day,data.Hour,data.Min,data.Sec)){
throw logic_error("時刻の描画に失敗しました");
}return 0;
}int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){
ChangeWindowMode(TRUE);
SetOutApplicationLogValidFlag(FALSE);
SetWindowText(_T("簡易スケジューラー"));
if(DxLib_Init()){
return -1;
}try{
if(SetWindowSize(WINWIDTH,WINHIGH)){
throw logic_error("初期化に失敗しました");
}if(SetAlwaysRunFlag(TRUE)){
throw logic_error("初期化に失敗しました");
}if(SetDrawScreen(DX_SCREEN_BACK)){
throw logic_error("初期化に失敗しました");
}if(SetFontSize(FONTSIZE)||SetFontThickness(FONTWIDTH)){
throw logic_error("初期化に失敗しました");
}if(SetKeyInputStringColor(
GetColor(0,0,0), GetColor(0,0,127),
GetColor(255,255,255), GetColor(0,127,0),
GetColor(0,127,127), GetColor(0,127,255),
GetColor(0,255,0), GetColor(0,255,127),
GetColor(0,255,255), GetColor(127,0,0),
GetColor(127,0,127), GetColor(127,0,255)
)){
throw logic_error("初期化に失敗しました");
}DATEDATA Time[2];
if(GetDateTime(&Time[0])){
throw logic_error("現在時刻の取得に失敗しました");
}WaitTimer(1000);
while(!ProcessMessage()){
if(GetDateTime(&Time[1])){
throw logic_error("現在時刻の取得に失敗しました");
}if(Time[0].Sec!=Time[1].Sec){
if(DrawWatch(Time[1])){
break;
}if(GetDateTime(&Time[0])){
throw logic_error("現在時刻の取得に失敗しました");
}
}if(CheckHitKey(KEY_INPUT_ESCAPE)){
break;
}if((CheckHitKey(KEY_INPUT_LCONTROL)||CheckHitKey(KEY_INPUT_RCONTROL))&&CheckHitKey(KEY_INPUT_P)){
if(SaveDrawScreen(0,0,WINWIDTH,WINHIGH,_T("Watch.bmp"))){
MessageBox(NULL,_T("印刷に失敗しました"),NULL,MB_OK);
}
}ScreenCopy();
}
}catch(logic_error &exc){
printfDx(_T("%s"),exc.what());
ScreenFlip();
MessageBoxA(NULL,exc.what(),NULL,MB_OK);
EndNum=1;
}catch(exception &exc){
printfDx(_T("%s"),exc.what());
ScreenFlip();
MessageBoxA(NULL,exc.what(),NULL,MB_OK);
EndNum=2;
}catch(...){
EndNum=3;
}DxLib_End();
return EndNum;
}
どうも、ウィンドウのサイズを640×480以外にし
たとき、「640×480のサイズで一端描画してからそ
のあとウィンドウサイズにあわせて拡大縮小する」
ようになっているように見受けられます。
実は以前のバージョン(3.05ぐらい)のときにも
似たような現象は発見していたのですが、そのとき
は自作のクラスライブラリを使用していたので、自
分のコードのバグなのかどうか判然としませんでし
た。
これはDxライブラリのバグなのでしょうか? それ
とも自分のソースコードに問題があるのでしょうか?
どうなっているのでしょうか?