Visual Studio2010とWin32API 子ウインドウが作成されません

解決


ひぐらし  2013-11-12 21:04:14  No: 73824

現在、タイトルの通りに子ウインドウを作成しようとしているのですがうまくいきません。
コンパイルは通るのですが、自作関数(C_Win.CreateChildWin)が吐き出すのがエラーになっています。
色々試してはいるのですがうまくいかなくて困っています。
エラーの原因がわかりましたら、教えて頂けないでしょうか?

#include <cmath>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include "Win.h"
#include "fft.h"
#include "resource.h"

Win::Win(void) {
};
Win::Win(HINSTANCE hInst) {
  infor.hInst=hInst;
};

ATOM Win::InitWin(void) {
  infor.wc.style=CS_HREDRAW|CS_VREDRAW,infor.wc.lpfnWndProc=WinProc;
  infor.wc.cbClsExtra=0,infor.wc.cbWndExtra=0,infor.wc.hInstance=this->infor.hInst;
  infor.wc.hIcon=LoadIcon(NULL,IDI_APPLICATION),infor.wc.hCursor=LoadCursor(NULL,IDC_ARROW);
  infor.wc.hbrBackground=(HBRUSH)COLOR_BACKGROUND+1;
  infor.wc.lpszMenuName=MAKEINTRESOURCE(IDR_MENU),infor.wc.lpszClassName=app_name;

  return RegisterClass(&this->infor.wc);
};
HWND Win::CreateParentWin(int nCmdShow) {
  if(!(infor.hw=CreateWindow(app_name,app_name,WS_OVERLAPPEDWINDOW,100,100,Win_width,Win_height,NULL,NULL,infor.hInst,NULL))) return false;
  else {
    ShowWindow(infor.hw,nCmdShow);
    UpdateWindow(infor.hw);
    return this->infor.hw;
  }
};
Win_infor Win::ShowInfor(void) {
  return this->infor;
}

W_Child::W_Child(void) {
}

ATOM W_Child::InitChildWin(HWND hw,LPCTSTR szClassName) {
  c_infor.wc.style=CS_HREDRAW|CS_VREDRAW,c_infor.wc.lpfnWndProc=C_WinProc;
  c_infor.wc.cbClsExtra=0,c_infor.wc.cbWndExtra=0,c_infor.wc.hInstance=this->infor.hInst;
  c_infor.wc.hIcon=NULL,c_infor.wc.hCursor=NULL;
  c_infor.wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
  c_infor.wc.lpszMenuName=NULL,c_infor.wc.lpszClassName=(LPCWSTR)szClassName;

  GetWindowRect(hw,(LPRECT)&(this->rect));

  return RegisterClass(&this->c_infor.wc);
};
HWND W_Child::CreateChildWin(HWND hw,int nCmdShow,HMENU hCId) {
  if(!(c_infor.hw=CreateWindow(app_name,NULL,WS_CHILD,0,0,rect.right-rect.left,(rect.bottom-rect.top)/2,hw,hCId,infor.hInst,NULL))) return false;
  else {
    ShowWindow(c_infor.hw,nCmdShow);
    UpdateWindow(c_infor.hw);
    return this->c_infor.hw;
  }
};

LRESULT CALLBACK WinProc(HWND hw,UINT uMsg,WPARAM wp,LPARAM lp) {
  HDC hdc;
  PAINTSTRUCT ps;
  COLORREF color;

  static HMENU tmp,hm;
  static OPENFILENAME ofn;
  static TCHAR f_namef[MAX_PATH],f_name[MAX_PATH];
  static data dat[anntena];
  W_Child C_Win;

  int iMsgID;

  switch(uMsg) {
  case WM_CREATE:
    if(!(C_Win.InitChildWin(hw,TEXT("解析結果"))&&C_Win.CreateChildWin(hw,SW_HIDE,(HMENU)IDR_CMENU))) {
      MessageBox(hw,TEXT("子ウインドウが作成できません"),TEXT("エラー"),MB_OK);
    }
    ZeroMemory(&ofn,sizeof(ofn));
    ofn.lStructSize=sizeof(ofn),ofn.hwndOwner=hw,ofn.lpstrFilter=TEXT("csv(*.csv)\0*.csv\0data(*.dat)\0*.dat\0\0");
    ofn.lpstrFile=f_namef,ofn.lpstrFileTitle=f_name,ofn.nMaxFile=sizeof(f_namef),ofn.nMaxFileTitle=sizeof(f_name);
    ofn.Flags=OFN_FILEMUSTEXIST|OFN_OVERWRITEPROMPT,ofn.lpstrTitle=TEXT("ファイルを開く"),ofn.lpstrDefExt=TEXT("csv");  
    
    tmp=LoadMenu(((LPCREATESTRUCT)(lp))->hInstance,TEXT("IDR_SUB"));
    hm=GetSubMenu(tmp,0);
    return 0;
  case WM_COMMAND:
    switch(LOWORD(wp)) {
    case IDM_EXIT:
      PostMessage(hw,WM_CLOSE,0,0);
      break;
    case IDM_FILEOPEN:
      if(GetOpenFileName(&ofn)) {
        std::vector<std::vector<complex>> tdat;
        std::ifstream ifs(f_name,std::ios::out);
        std::string buf;

        if(ifs.fail()) {
          MessageBox(hw,TEXT("ファイルが開けません"),TEXT("エラー"),MB_OK);
          break;
        }

        int k=0;
        double N=0,nu=0.0;
        while(ifs&&getline(ifs,buf)) {
          if(k<13) {
          } else {
            std::replace(buf.begin(),buf.end(),',',' ');
            std::istringstream stream(buf);
            std::vector<complex> tmp;

            stream >> N >> nu;
            double val1=0.0,val2=0.0;
            for(int i=0;i<anntena;i++) {
              stream >> val1 >> val2;
              tmp.push_back(set(val1,val2));
            }
            tdat.push_back(tmp);
          }
          k++;
        }
        ifs.close();
        N=pow(2.0,(int)log2(N));
        for(int i=0;i<anntena;i++) {
          dat[i].Z=new complex[(int)N],dat[i].N=N;
        }
        for(int i=0;i<N;++i) {
          for(int j=0;j<anntena;++j) {
            dat[j].Z[i]=tdat[i][j];
          }
        }
      }
      MessageBox(hw,TEXT("読み込み終了"),TEXT(""),MB_OK);
      break;
    case IDM_ANALYSIS:
      for(int i=0;i<anntena;++i) {
        fft fft(dat[i]);
        if(fft.bfy(true)) {
          ofn.lpstrTitle=TEXT("ファイルを保存する");
          if(GetSaveFileName(&ofn)) {
            fft.save(f_name);
          }
        }
      }
      MessageBox(hw,TEXT("保存終了"),TEXT(""),MB_OK);
      break;
    }
    return 0;
  case WM_RBUTTONUP:
    POINT point;
    point.x=LOWORD(lp),point.y=HIWORD(lp);

    ClientToScreen(hw,&point);
    TrackPopupMenu(hm,TPM_LEFTALIGN|TPM_TOPALIGN,point.x,point.y,0,hw,NULL);
    return 0;
  case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
  }

  return DefWindowProc(hw,uMsg,wp,lp);
}

LRESULT CALLBACK C_WinProc(HWND hw,UINT uMsg,WPARAM wp,LPARAM lp) {
  HDC hdc;
  PAINTSTRUCT ps;
  COLORREF color;
  RECT rect;

  static HMENU tmp,hm;
  static TCHAR f_namef[MAX_PATH],f_name[MAX_PATH];

  int iMsgID;

  switch(uMsg) {
  case WM_CREATE:
    return 0;
  case WM_COMMAND:
    switch(LOWORD(wp)) {
    }
  }

  return DefWindowProc(hw,uMsg,wp,lp);
}


瀬戸っぷ  2013-11-14 06:39:37  No: 73825

CreateWindow()が失敗したらHWNDとしてfalseを返却…ですか?

WinProc()内のC_Winが正しく初期化できているのか不明ですし、
c_inforがどんなモノなのかも不明です。

まぁとりあえず…
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632679%28v=vs.85%29.aspx
GetLastError()
でCreateWindow()が失敗した原因を調べるのが先決…でしょうかね。


ひぐらし  2013-11-16 00:01:45  No: 73826

瀬戸っぷ様、回答ありがとうございます。

>CreateWindow()が失敗したらHWNDとしてfalseを返却…ですか?
これはメインソースで、エラーメッセージを吐き出すためのもので、特に意味はありません。

>WinProc()内のC_Winが正しく初期化できているのか不明ですし、
c_inforがどんなモノなのかも不明です。
c_inforの定義はこれです

struct Win_infor {
  HINSTANCE hInst;
  HDC hdc;
  HWND hw;
  WNDCLASS wc;
  MSG msg;
};

早速GetLastErrorを使ったところ、
C_Win.CreateChildWin(hw,SW_HIDE,(HMENU)IDR_CMENU))
の関数でウインドウクラスが見つかりません
と出てきました。
親ウインドウは同じようにやってもエラーにならなかったのに、ここではなります。これは子ウインドウだから仕様が違うのでしょうか?

後、参考にしたサイトはこちらです。
http://emboss.blog28.fc2.com/blog-entry-115.html


瀬戸っぷ  2013-11-16 11:57:54  No: 73827

>早速GetLastErrorを使ったところ、
>C_Win.CreateChildWin(hw,SW_HIDE,(HMENU)IDR_CMENU))
>の関数でウインドウクラスが見つかりません
>と出てきました。

ウィンドウクラスはあるみたいですけどねぇ。
ただしループしますが。

親ウィンドウの作成でapp_nameのウィンドウクラスで指定されたWinProc()にWM_CREATEが発行される。
WM_CREATEでCreateWindow()→app_nameのウィンドウクラスで指定されたWinProc()にWM_CREATEが発行される。
WM_CREATEでCreateWindow()→app_nameのウィンドウクラスで指定されたWinProc()にWM_CREATEが発行される。
WM_CREATEでCreateWindow()→app_nameのウィンドウクラスで指定されたWinProc()にWM_CREATEが発行される。
WM_CREATEでCreateWindow()→app_nameのウィンドウクラスで指定されたWinProc()にWM_CREATEが発行される。
WM_CREATEでCreateWindow()→app_nameのウィンドウクラスで指定されたWinProc()にWM_CREATEが発行される。
    :

W_Child::CreateChildWin()で、子ウィンドウのウィンドウプロシージャはWinProc()ですよ。と指定していますからね。
指定するウィンドウクラスはC_Win.InitChildWin(hw,TEXT("解析結果"))で作成しているモノじゃないんですか?
c_infor.wc.lpszClassNameに入っているようですが…。


ひぐらし  2013-11-19 11:07:46  No: 73828

瀬戸様、回答ありがとうございます。

そういうことなんですね、自分が勉強不足でした。
今日試せないので明日さっそく試してみます!!


ひぐらし  2013-11-20 23:37:46  No: 73829

無事に解決しました、ありがとうございます!!


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加