DxLibFanに戻る

/**
@file screen_saver.cpp
@brief スクリーンセーバーを作る時に使用。
@author d金魚
@since 2005/02/06
@note
コマンドラインにwを入れるとWindowModeで起動できる。
ライセンスはNYSLです。御自由にお使いください。
*/


#ifndef DXEX_SCREEN_SAVER_HPP
#define DXEX_SCREEN_SAVER_HPP

//#include "DxLib.h"
#include <windows.h>
//#include <mmsystem.h>
#include <winnls32.h>
#include <regstr.h>
#include <tchar.h>
/////マウスムーブチェックのカウント
#define DEF_MMOVE_COUNT 0

#ifndef _MSC_VER

#include <dkutil/macro.hpp>

#endif

namespace dxex{

class ScreenSaverApplication{
public:
#ifdef _MSC_VER
  enum{
    SSaverSetDataDialog=1,
    SSaverPreview,
    SSaverFullScreen,
    SSaverChangePasswd,
    ///デバッグ用
    SSaverWindowMode,
  };
#else
  BOOST_STATIC_CONSTANT(int,SSaverSetDataDialog = 1);
  BOOST_STATIC_CONSTANT(int,SSaverPreview = 2);
  BOOST_STATIC_CONSTANT(int,SSaverFullScreen = 3);
  BOOST_STATIC_CONSTANT(int,SSaverChangePasswd = 4);
  BOOST_STATIC_CONSTANT(int,SSaverWindowMode = 5);

#endif

  typedef BOOL (WINAPI *VERIFYPWDPROC)(HWND);
  typedef VOID (WINAPI *PWDCHANGEPASSWORD)(LPCTSTR, HWND, DWORD, LPVOID);

  typedef struct _tugDKINGYO_SAVERDATA{
    bool bPreview;
    bool bWin9x;
    LPSTR lpCmdLine;
    HINSTANCE hInstance;
    HINSTANCE  hInstPwdDLL;
    VERIFYPWDPROC VerifyPassword;
    WORD Resorce;
    DLGPROC lpDialogFunc ;
    POINT mMouseXY;
    DWORD mWakeThreshold;
  }SDATA;


  ScreenSaverApplication(){
    variable_init();
  }
  virtual ~ScreenSaverApplication(){
    saver_end();
  }
  int init(HINSTANCE hInst,LPSTR lpCmdLine,WORD Resorce,DLGPROC lpDialogFunc ){
    saver_end();
    variable_init();
    int r = DxLibScreenSaverStateSet(&hInst,&lpCmdLine,Resorce,lpDialogFunc );

    return r;
  }
  /*bool dxlib_init(){
    return (0 == MyDxLibInit(mWindowFlag));
  }*/
  bool saver_end(){
    if(mDxLibInitFlag == false){
      return false;
    }
    bool r =  (0==DxLibScreenSaverEnd());
    mDxLibInitFlag = false;
    return r;
  }
  /**
  @param autoexitflag[in] trueでパスワードチェックでOK、または、終了条件だったら自動でソフト自体を終了
  @return チェックが成功だったらtrue
  */
  ///パスワードをチェックする。
  bool check_password(bool autoexitflag){
    return CheckPasswd(autoexitflag);
  }
  ///DxLibが初期化にエラーしたらTRUE
  bool isDxLibError()const{
    return mIsDxLibError;
  }


private:
  HANDLE  mMutex;
  SDATA s;
  int mx,my;
  int hx,hy;
  int getx,gety;
  bool check;
  BYTE mSaverMouseMoveCheck;
  int count;
  bool mWindowFlag;
  bool mDxLibInitFlag;
  bool mIsDxLibError;

  void variable_init(){
    mMutex = NULL;
    //ZeroMemory(&mMouseXY,sizeof(mMouseXY));
    ZeroMemory(&s,sizeof(SDATA));
    s.mWakeThreshold = 4;
    mx = my = 0;
    check =false;
    mSaverMouseMoveCheck = 0;
    count = 0;
    mWindowFlag = false;
    mDxLibInitFlag = false;
    mIsDxLibError = false;
  }
  void LoadPwdDLL(void)
  {
    if(!s.bWin9x) return;
    
    if(s.hInstPwdDLL) UnloadPwdDLL();
    
    HKEY hKey;
    if(RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE, &hKey) == ERROR_SUCCESS) {
      DWORD dwVal, dwSize = sizeof(dwVal);
      if((RegQueryValueEx(hKey, REGSTR_VALUE_USESCRPASSWORD, NULL, NULL, (BYTE *)&dwVal, &dwSize) == ERROR_SUCCESS) && dwVal) {
        if(s.hInstPwdDLL = LoadLibrary(_T("PASSWORD.CPL"))) {
          s.VerifyPassword = (VERIFYPWDPROC)GetProcAddress(s.hInstPwdDLL, "VerifyScreenSavePwd");
          if(s.VerifyPassword) {
            BOOL  dummy;
            SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &dummy, 0);
          } else {
            UnloadPwdDLL();
          }
        }
      }
      RegCloseKey(hKey);
    }
  }
  void UnloadPwdDLL(void)
  {
    if(!s.bWin9x) return;
    
    if(s.hInstPwdDLL) {
      FreeLibrary(s.hInstPwdDLL);
      s.hInstPwdDLL = NULL;
      
      if(s.VerifyPassword) {
        s.VerifyPassword = NULL;
        BOOL  dummy;
        SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &dummy, 0);
      }
    }
  }
  
  /**
  @param flag[in] trueでWindowモード
  */
  int MyDxLibInit(bool flag = false){
    int r=-1;
    if(    mDxLibInitFlag == true){
      return r;
    }
    ChangeWindowMode((int)flag);
    SetOutApplicationLogValidFlag(FALSE ) ;

    r = DxLib_Init();
    if(-1==r)
      return r;

    SetDrawScreen(DX_SCREEN_BACK);
    SetUseGDIFlag(TRUE) ;
    mDxLibInitFlag = true;
    return r;

  }
  static LRESULT CALLBACK RealScreenSaverProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  {
    static SDATA *ps;
    switch(uMsg) {
    case WM_INITDIALOG:
    case WM_CREATE:
      //定石テクニック
      ps = (SDATA *)lParam;
      if(!ps->bPreview) {
        while(ShowCursor(FALSE) >= 0);
        WINNLSEnableIME(NULL, FALSE);
      }
      break;

    case WM_DESTROY:
      if(!ps->bPreview) {
        while(ShowCursor(TRUE) < 0);
        WINNLSEnableIME(NULL, TRUE);
      }
      ShowWindow(hWnd, SW_HIDE);
      PostQuitMessage(0);
      break;

    case WM_SYSCOMMAND:
      if(!ps->bPreview) {
        switch (wParam) {
        case SC_NEXTWINDOW:
        case SC_PREVWINDOW:
        case SC_SCREENSAVE:
          return FALSE;
        }
      }
      break;

    case WM_HELP:
    case WM_CONTEXTMENU:
      if(ps->bPreview) {
        HWND hParent = GetParent(hWnd);
        if(hParent && IsWindow(hParent)) PostMessage(hParent, uMsg, (WPARAM)hParent, lParam);
        return TRUE;
      }
      break;
    }
    return ScreenSaverProc(hWnd, uMsg, wParam, lParam);
  }

  int DoScreenSave(HWND hWndParent)
  {
    int r = -1;
    LPCTSTR  lpCassName = _T("DxLibScreenSaverClass");
    LPCTSTR  lpWindowName;
    HINSTANCE hInst=s.hInstance;
    

    DWORD  dwStyle, dwExStyle;
    int    nWidth, nHeight;

    if(!hWndParent) {
      if(!s.bPreview) {
        if(mWindowFlag){//mWindowFlag自体を突っ込めば良いのにね^^;
          r = MyDxLibInit(mWindowFlag);
        }else{
          //フルスクリーン
          r = MyDxLibInit(FALSE);
        }
        
      } else {
        //WindowMode
        r = MyDxLibInit(TRUE);
        

        
      }
      if(0 != r){
        mIsDxLibError = true;
      }else{
        mIsDxLibError = false;
      }
      
      lpWindowName = _T("Screen Saver");

      mMutex = CreateMutex(NULL, FALSE, _T("SCRNSAVE"));
      if(!mMutex || GetLastError() == ERROR_ALREADY_EXISTS) return 0;

      LoadPwdDLL();

      return 0;
    } else {
      //完璧なプレビュー
      RECT rect;
      GetClientRect(hWndParent, &rect);
      nWidth = rect.right;
      nHeight = rect.bottom;
      dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
      dwExStyle = 0;
      
      lpWindowName = _T("Preview");

      WNDCLASS  wc;
      wc.style     = CS_OWNDC;
      wc.lpfnWndProc   = (WNDPROC)RealScreenSaverProc;
      wc.cbClsExtra   = 0;
      wc.cbWndExtra   = 0;
      wc.hInstance   = hInst;
      wc.hIcon     = NULL;
      wc.hCursor     = LoadCursor(NULL, IDC_ARROW);
      wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
      wc.lpszMenuName   = NULL;
      wc.lpszClassName = lpCassName;

      HWND  hWnd = NULL;
      if(RegisterClass(&wc)) {
        hWnd = CreateWindowEx(
          dwExStyle,
          lpCassName,
          lpWindowName,
          dwStyle,
          0, 0,
          nWidth, nHeight,
          hWndParent,
          NULL,
          hInst,
          NULL
        );
      }
      MSG  msg;
      __try {
        timeBeginPeriod(1);

        if(hWnd /*&& Initialize(hWnd, hWndParent)*/) {
          //GetCursorPos(&mMouseXY);
          for(;;) {
            if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
              if(!GetMessage(&msg, NULL, 0, 0)) break;
              TranslateMessage(&msg);
              DispatchMessage(&msg);
            } else {
              //UpdateFrame(hWnd);
            }
          }
        }
      } 
      __finally {
        timeEndPeriod(1);
        //Cleanup(hWnd);
        UnloadPwdDLL();
        if(mMutex) ReleaseMutex(mMutex);
      }
      return msg.wParam;
    }

    
    return 0;
    
  }

  BYTE GetSaverMouseMoveCheck(){
    if(mSaverMouseMoveCheck==0)
      mSaverMouseMoveCheck=10;

    return mSaverMouseMoveCheck;
  }
  /*
//レジストリの名前
#define REG_G "GrahpicFileName"
#define REG_M "MusicFileName"
#define REG_MMOVE "MouseMoveDot"
//マウスムーブチェックのカウント
#define DEF_MMOVE_COUNT 0

static char szGraphicFileName[MAX_PATH];
static char szGraphicFilePath[MAX_PATH];

static char szMusicFileName[MAX_PATH];
static char szMusicFilePath[MAX_PATH];




BYTE (*TestTestTest)(void)=NULL;//テストの関数のポインタ

void SetTestFunc(BYTE (*f)(void)){
  TestTestTest=f;
}


char *GetGraphicFileNamePointer(char **p){
  if(p!=NULL)
    *p=szGraphicFileName;
  return szGraphicFileName;
}

char *GetMusicFileNamePointer(char **p){
  if(p!=NULL)
    *p=szMusicFileName;
  return szMusicFileName;
}
*/


  bool DoSaverPreview(LPCSTR Handle)
  {
     s.bPreview = TRUE;
     HWND hParent;
     hParent= (HWND)atoi(Handle);
     if((hParent && IsWindow(hParent))){
        DoScreenSave(hParent); 
    }else    
      return false;
    
    return true;
  }

  int DxLibScreenSaverEnd(void){
    DxLib_End();
    if(mMutex) ReleaseMutex(mMutex);
    UnloadPwdDLL();
    return 0;
  }
  ///最初の初期化をする。
  int DxLibScreenSaverStateSet(HINSTANCE *hInst,LPSTR *lplpCmdLine,WORD Resorce,DLGPROC lpDialogFunc ){
    s.hInstance=NULL;
    s.hInstPwdDLL=NULL;
    s.VerifyPassword=NULL;
    s.Resorce = Resorce;
    s.lpDialogFunc = lpDialogFunc;
    s.lpCmdLine = *lplpCmdLine;
    s.hInstance = *hInst;

    LPSTR lpCmdLine = *lplpCmdLine;
    int result=NULL;
      
     
    
    OSVERSIONINFO osvi;
    osvi.dwOSVersionInfoSize = sizeof(osvi);
    s.bWin9x = (GetVersionEx(&osvi) && osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
    
    //コマンドラインパース
    //参考:http://home.att.ne.jp/yellow/hide_n/programming/dx8tips03a.html
    char *p = lpCmdLine;
    //for(p;p != '\0';p++){

    
    while(true){
      if(result!=0)
        break;

      switch(*p)
      {
      case 'W'://個人的にデバッグ用
      case 'w':
        mWindowFlag = TRUE;
        (int)DoScreenSave(NULL);
        result = SSaverWindowMode;
        break;
        //s.bPreview = TRUE;
      case 'S':
      case 's':
         (int)DoScreenSave(NULL);
         result = SSaverFullScreen;
         break;
      case 'P':
      case 'p':
        do{
          p++;
        }while(*p == ' ');
        (int)DoSaverPreview(p);
        result = SSaverPreview;
        break;

      case 'A':
      case 'a':
        if(!s.bWin9x) return -1;
        do{
          p++;
        }while(*p == ' ');
        DoChangePw(p);
        result = SSaverChangePasswd;
        break;
        
      case 'C':
      case 'c':
        (int)DoConfigBox(GetForegroundWindow(),s.Resorce,s.lpDialogFunc);
        result = SSaverSetDataDialog;
        break;

      case '\0':
        (int)DoConfigBox(NULL,s.Resorce,s.lpDialogFunc);
        result = SSaverSetDataDialog;
        break;

      /*case ' ':
      case '-':
      case '/':
        p++;
        break;*/
        
      default:
        break;
      }
      p++;
    }
    /*
    while(true){
      if(result!=NULL)
        break;
      switch(*lpCmdLine)
      {
      case 'W':
      case 'w':
        s.bPreview = TRUE;
      case 'S':
      case 's':
         (int)DoScreenSave(NULL);
         result = SSaverFullScreen;
         break;
      case 'P':
      case 'p':
        do lpCmdLine++; while(*lpCmdLine == ' ');
        (int)DoSaverPreview(lpCmdLine);
        result = SSaverPreview;
        break;

      case 'A':
      case 'a':
        if(!s.bWin9x) return -1;
        do{
          lpCmdLine++;
        }while(*lpCmdLine == ' ');
        DoChangePw(lpCmdLine);
        result = SSaverChangePasswd;
        break;
        
      case 'C':
      case 'c':
        (int)DoConfigBox(GetForegroundWindow(),s.Resorce,s.lpDialogFunc);
        result = SSaverSetDataDialog;
        break;

      case '\0':
        (int)DoConfigBox(NULL,s.Resorce,s.lpDialogFunc);
        result = SSaverSetDataDialog;
        break;

      case ' ':
      case '-':
      case '/':
        lpCmdLine++;
        break;
        
      default:
        return 0;
      }

    }*/
    return result;
  }

  ///パスワードをチェンジする
  int DoChangePw(LPCSTR szUINTHandle)
  {
    HWND hParent = (HWND)atoi(szUINTHandle);

    if(!hParent || !IsWindow(hParent))
      hParent = GetForegroundWindow();

    HINSTANCE hMprDll = LoadLibrary(_T("MPR.DLL"));

    if(hMprDll){
      PWDCHANGEPASSWORD PwdChangePassword;

  #ifdef UNICODE
      PwdChangePassword = (PWDCHANGEPASSWORD)GetProcAddress(hMprDll, "PwdChangePasswordW");
  #else
      PwdChangePassword = (PWDCHANGEPASSWORD)GetProcAddress(hMprDll, "PwdChangePasswordA");
  #endif

      if(PwdChangePassword != NULL)
        PwdChangePassword(_T("SCRSAVE"), hParent, 0, NULL);

      FreeLibrary(hMprDll);
    }
    return 0;
  }
  ///デフォルトのスクリーンセーバーのコールバック
  static LRESULT CALLBACK DefScreenSaverProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  {
    static SDATA *ps  = NULL;
    switch(uMsg){
    case WM_CREATE:
    case WM_INITDIALOG:
      ps = (SDATA *)lParam;
      break;
    }
    if(!ps->bPreview) {
      switch(uMsg) {
      case WM_CLOSE:
        if(!ps->bPreview) {
          while(ShowCursor(TRUE) < 0);
          WINNLSEnableIME(NULL, TRUE);
          if(ps->bWin9x) {
            if(!DoPasswordCheck(hWnd,ps->VerifyPassword)) {
              GetCursorPos(&(ps->mMouseXY));
              while(ShowCursor(FALSE) >= 0);
              WINNLSEnableIME(NULL, FALSE);
              return FALSE;
            }
          }
        }
        break;

      default:
        switch( uMsg )
        {
        case WM_MOUSEMOVE:
          {
            POINT ptMove, ptCheck;
          
            GetCursorPos(&ptCheck);
            ptMove.x = ptCheck.x - ps->mMouseXY.x;
            if(ptMove.x < 0) ptMove.x = -ptMove.x;
            ptMove.y = ptCheck.y - ps->mMouseXY.y;
            if(ptMove.y < 0) ptMove.y = -ptMove.y;
            if(((DWORD)ptMove.x + (DWORD)ptMove.y) > ps->mWakeThreshold) {
              PostMessage(hWnd, WM_CLOSE, 0, 0l);
              ps->mMouseXY = ptCheck;
            }
          }
          break;
          
        case WM_ACTIVATEAPP:
          if(wParam) break;
        case WM_LBUTTONDOWN:
        case WM_MBUTTONDOWN:
        case WM_RBUTTONDOWN:
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
          PostMessage(hWnd, WM_CLOSE, 0, 0l);
          break;
        }
      }
    }  
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }


  ///DefScreenSaverProc()のWrapper
  static LRESULT CALLBACK ScreenSaverProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  {
    return DefScreenSaverProc(hWnd, uMsg, wParam, lParam);
  }

  static BOOL DoPasswordCheck(HWND hWnd,VERIFYPWDPROC VerifyPassword)
  {
    if(VerifyPassword){
      return VerifyPassword(hWnd);
    }

    return TRUE;
  }

  LRESULT  DoConfigBox(HWND hWnd,WORD RESOURCENAME,DLGPROC DlgProc)
  {
    return DialogBox(s.hInstance, MAKEINTRESOURCE(RESOURCENAME), hWnd, DlgProc);
  }






  bool CheckPasswd(bool autoflg){
    bool r=false;

    static bool check1=false;
    static int counter=0;
    static int go_count=100;
    
    if(check1==false){
      if(CheckDxLibSaverKeyAndMouse()){
        check1=true;    
        if(!DoPasswordCheck(GetMainWindowHandle(),s.VerifyPassword)){
          {//ダミー
              int dx,dy;
              GetMousePoint( &dx, &dy );
              count++;
              mx=getx=dx;
              my=gety=dy;
          }
        }else{
          r=true;      
          if(autoflg==true)
          {//autoなら強制終了
            //DxLibScreenSaverEnd();
            saver_end();
            exit(1);
          }
        }
      }
    }else{
      counter++;
      if(counter>50){
        counter=0;
        check1=false;
      }
    }

    return r;
  }

  bool CheckDxLibSaverKeyAndMouse(bool *f=NULL){
    
    check=false;
    
    if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) == 0 )
    {
      // 押されていない
    }
    else
    {
      // 押されている
  #ifdef _MYDEBUG
      printfDx("MOUSE INPUT LEFT");
  #endif
      check=true;
    }
    if( ( GetMouseInput() & MOUSE_INPUT_RIGHT ) == 0 )
    {
      // 押されていない
    }
    else
    {
  #ifdef _MYDEBUG
      printfDx("MOUSE INPUT RIGHT");
  #endif
      // 押されている
      check=true;
    }
    if( ( GetMouseInput() & MOUSE_INPUT_MIDDLE ) == 0 )
    {
      // 押されていない
    }
    else
    {
  #ifdef _MYDEBUG
      printfDx("MOUSE INPUT MIDDLE");
  #endif
      // 押されている
      check=true;
    }

    GetMousePoint( &getx, &gety );

    if(getx > mx){
      if(GetSaverMouseMoveCheck()<(hx=getx-mx)){
  #ifdef _MYDEBUG
        printfDx("hx=%d\n",hx);
  #endif
        if(count>DEF_MMOVE_COUNT){
          mx=getx;my=gety;
          check= true;
        }
      }
    }else{
      if(GetSaverMouseMoveCheck()<(hx=mx-getx)){
  #ifdef _MYDEBUG
        printfDx("else hx=%d\n",hx);
  #endif
        if(count>DEF_MMOVE_COUNT){
          mx=getx;my=gety;
          check= true;
        }
      }
    }

    if(gety>my){
      if(GetSaverMouseMoveCheck()<(hy=gety-my)){
  #ifdef _MYDEBUG
        printfDx("hy =%d\n",hy);
  #endif
        if(count>DEF_MMOVE_COUNT){
          mx=getx,my=gety;
          check= true;
        }
      }
    }else{
      if(GetSaverMouseMoveCheck()<(hy=my-gety)){
  #ifdef _MYDEBUG
        printfDx("else h=%d\n",hy);
  #endif
        if(count>DEF_MMOVE_COUNT){
          mx=getx,my=gety;
          check= true;
        }
      }
    }

    mx=getx;
    my=gety;

  #ifdef _MYDEBUG
    int c=GetColor(255,255,255);
    DrawFormatString(0,0,c,"getx=%d,gety=%d,mx=%d,my=%d",getx,gety,mx,my);
    //clsDx();
  #endif
    
    

    if(CheckHitKeyAll() != 0){
  #ifdef _MYDEUBG
      printfDx("CHECK HITKEY ALL");
  #endif
      check=true;
    }


    
    if(f!=NULL){
      *f=check;
    }
    count++;
    return check;
  }













};

}//end of namespace


#endif






/**
@file screen_saver.cpp
@brief スクリーンセーバーのサンプル
*/
#include <DxLibMake/DxLib.h> 
#include <dxex/screen_saver.hpp>
//#include <dkutil_c/dkc.h>

int gScreenWidth = 640;
int gScreenHeight = 480;


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
         LPSTR lpCmdLine, int nCmdShow )
{
  //dkcCheckMemoryLeak(TRUE);

  typedef dxex::ScreenSaverApplication SSAVER;
  SSAVER app;
  int r = app.init(hInstance,lpCmdLine,NULL,NULL);

  if(app.isDxLibError()){
    goto End;
  }
  /*
  MessageBox(NULL,lpCmdLine,"コマンドライン",MB_OK);
  MessageBox(NULL,GetCommandLine(),"コマンドライン",MB_OK);
  */
  if(r== SSAVER::SSaverFullScreen || SSAVER::SSaverWindowMode == r)
  {


    while(ProcessMessage() !=-1)
    {
      
      if(CheckHitKey(KEY_INPUT_ESCAPE)==1){
        break;
      }
      //パスワードチェック
      if(app.check_password(false)){
        break;
      }
        
      DrawFormatString(0,0,GetColor(255,255,255),"DrawFormatString");

      ScreenFlip();
      Sleep(30);
      
    }
    app.saver_end();
  
  }
End:
  return 0;
}

SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送