質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3073閲覧

ボタンを押すともう一つウィンドウが開くプログラムを作りたい

tometome

総合スコア27

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/08/12 07:54

そのプログラムを書いたのですが、なぜかボタンを押すとウィンドウが開く時と開かずに終了してしまう時があります。どこを修正すればいいでしょうか。win apiなのでコードが長くなりますが、(ファイルをアップロードする方法も分からないので)一応全部ここに載せます。あと面倒でなければこのコードの中で「こういう風には書いてしまうのは絶対避けるべき」などの点があったらそれも教えてください。


header.hpp

lang

1#include<windows.h> 2 3//window placement 4#define COORD_X 700 5#define COORD_Y 0 6 7//window size 8#define W_LENTH 800 9#define W_WIDTH 700 10 11//Window Style 12#define MAIN_WND_STYLE WS_OVERLAPPEDWINDOW 13#define BSTYLE BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD 14 15class WINDOWOBJECT{ 16 HWND Button; 17 HWND Wnd_s1; 18public: 19 void WM_CREATEfunc(HWND, LPCREATESTRUCT); 20 void Button_func(HWND, LPCREATESTRUCT); 21}; 22 23LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); 24LRESULT CALLBACK WindowProc_s1(HWND, UINT, WPARAM, LPARAM); 25void WM_COMMANDfunc(HWND, WPARAM, LPARAM, WINDOWOBJECT&);


WinMain.cpp

lang

1#include "header.hpp" 2 3int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow){ 4 WNDCLASSEX wc; 5 wc.cbSize = sizeof(WNDCLASSEX); 6 wc.style = CS_HREDRAW | CS_VREDRAW; 7 wc.lpfnWndProc = WindowProc; 8 wc.cbClsExtra = 0; 9 wc.cbWndExtra = 0; 10 wc.hInstance = hInstance; 11 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 12 wc.hCursor = LoadCursor(NULL, IDC_ARROW); 13 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 14 wc.lpszMenuName = NULL; 15 wc.lpszClassName = "MainWndClass1"; 16 wc.hIconSm = NULL; 17 18 if(!RegisterClassEx(&wc)) return FALSE; 19 20 HWND hWnd; 21 hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, wc.lpszClassName, "Title", 22 MAIN_WND_STYLE, COORD_X, COORD_Y, W_WIDTH, W_LENTH, 23 NULL, NULL, hInstance, NULL); 24 25 if(hWnd == NULL) return FALSE; 26 27 ShowWindow(hWnd, nCmdShow); 28 UpdateWindow(hWnd); 29 30 MSG msg; 31 BOOL bRet; 32 33 while(bRet = GetMessage(&msg, NULL, 0, 0)){ 34 if(bRet == -1){ 35 MessageBox(NULL, "Message loop error", "alert", MB_OK); 36 return 0; 37 } 38 39 TranslateMessage(&msg); 40 DispatchMessage(&msg); 41 } 42 43 return msg.wParam; 44} 45 46LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ 47 static WINDOWOBJECT WndOb; 48 switch(uMsg){ 49 case WM_CREATE: WndOb.WM_CREATEfunc(hWnd, (LPCREATESTRUCT)lParam); break; 50 case WM_COMMAND: WM_COMMANDfunc(hWnd, wParam, lParam, WndOb); break; 51 case WM_DESTROY: PostQuitMessage(0); break; 52 default: return DefWindowProc(hWnd, uMsg, wParam, lParam); 53 } 54 55 return 0; 56}


WM_COMMANDfunc.cpp

lang

1#include "header.hpp" 2 3void WM_COMMANDfunc(HWND hWnd, WPARAM wParam, LPARAM lParam, WINDOWOBJECT &WndOb){ 4 switch(LOWORD(wParam)){ 5 case 10: WndOb.Button_func(hWnd, (LPCREATESTRUCT)lParam); 6 } 7}


WM_CREATEfunc.cpp

lang

1#include "header.hpp" 2 3void WINDOWOBJECT::WM_CREATEfunc(HWND hWnd, LPCREATESTRUCT lpCreateStruct){ 4 Button = CreateWindow("button", NULL, BSTYLE, 250, 380, 60, 30, hWnd, (HMENU)10, 5 lpCreateStruct->hInstance, NULL); 6 UpdateWindow(Button); 7}


Button_func.cpp

lang

1#include "header.hpp" 2 3void WINDOWOBJECT::Button_func(HWND hWnd, LPCREATESTRUCT lpCreateStruct){ 4 WNDCLASSEX wc; 5 wc.cbSize = sizeof(WNDCLASSEX); 6 wc.style = CS_HREDRAW | CS_VREDRAW; 7 wc.lpfnWndProc = WindowProc_s1; 8 wc.cbClsExtra = 0; 9 wc.cbWndExtra = 0; 10 wc.hInstance = lpCreateStruct->hInstance; 11 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 12 wc.hCursor = LoadCursor(NULL, IDC_ARROW); 13 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 14 wc.lpszMenuName = NULL; 15 wc.lpszClassName = "SubWndClass1"; 16 wc.hIconSm = NULL; 17 18 RegisterClassEx(&wc); 19 Wnd_s1 = CreateWindowEx(WS_EX_CLIENTEDGE, wc.lpszClassName, NULL, 20 WS_VISIBLE | WS_CAPTION | WS_SYSMENU, 21 COORD_X + 10, COORD_Y, W_WIDTH - 50, W_LENTH - 50, 22 hWnd, NULL, lpCreateStruct->hInstance, NULL); 23 24 ShowWindow(Wnd_s1, SW_SHOW); 25 UpdateWindow(Wnd_s1); 26 27 MSG msg; 28 BOOL bRet; 29 30 while(bRet = GetMessage(&msg, NULL, 0, 0)){ 31 if(bRet == -1){ 32 MessageBox(NULL, "Message loop error", "alert", MB_OK); 33 break; 34 } 35 36 TranslateMessage(&msg); 37 DispatchMessage(&msg); 38 } 39 40 DestroyWindow(Wnd_s1); 41} 42 43LRESULT CALLBACK WindowProc_s1(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ 44 switch(uMsg){ 45 case WM_DESTROY: PostQuitMessage(0); break; 46 default: return DefWindowProc(hWnd, uMsg, wParam, lParam); 47 } 48 49 return 0; 50}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Windowシステムに対するいくつかの誤解があるようです。

  1. lParamは常にLPCREATESTRUCTというわけではない
  2. umsg == WM_COMMAND && LOWORD(wParam) == ボタンのID だからといって常にボタンが押下された通知とは限らない

以上2点は、Notification Messages from Buttonsこちらを参照してください
3. ウィンドウを開くたびにWindowClassの登録が必要ではない
同一のウィンドウプロシージャであるならば使いまわしてもよい

投稿2019/08/12 16:20

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tometome

2019/08/13 08:49

私はインターネットのサイトを見て、winapiの基本的な部分を勉強して、そのサイトにlParamをLPCREATESTRUCTにキャストしてhInstanceを使っていた部分があったので、何も考えずそれを続けてきて今まで何も起こらなかったので間違いに気が付かなかったです。hInstanceは元のをそのまま使うことにしました。指摘された3つのことを一気に直したので動作がおかしかった原因がどれなのかは分かりませんでしたが、修正後はウインドウが開かないということはなくなりました。回答ありがとうございます。おかげで解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問