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

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

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

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

C++

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

Q&A

3回答

2997閲覧

C++とwinapiでのボタン作成

uenotokyoline

総合スコア15

Win32 API

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

C++

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

0グッド

0クリップ

投稿2019/04/01 06:28

編集2019/04/01 14:39

#現在やっていること
現在C++を学びながらソフトを制作しようとしております。そこでQtとかGUIのライブラリを使う手もあったのですがやはりwinapiで作ったほうがいろいろデザインもできるし学べることも多いのかなと(結局はライブラリもwinapi使ってるかな)winapiで制作してます。しかし情報が極めて不足していてほとんどがC#か.NETの情報です。

#困ったこと
####1.四角形が黒枠がついてしまう<解決済み>
黒枠を消したいです
イメージ説明

C++

1case WM_DRAWITEM: 2 hdc = ((LPDRAWITEMSTRUCT)(lp))->hDC; 3 4 if (((LPDRAWITEMSTRUCT)(lp))->itemState & ODS_SELECTED) { 5 SelectObject(hdc, CreateSolidBrush(RGB(80, 91, 109))); 6 std::cout<<"[INFO] ON\n"; 7 }else { 8 SelectObject(hdc, CreateSolidBrush(RGB(73, 147, 120))); 9 std::cout<<"[INFO] OFF\n"; 10 } 11 Rectangle(hdc , 0 , 0 , 12 ((LPDRAWITEMSTRUCT)(lp))->rcItem.right , 13 ((LPDRAWITEMSTRUCT)(lp))->rcItem.bottom 14 ); 15 DeleteObject(SelectObject(hdc , GetStockObject(WHITE_BRUSH))); 16 return TRUE;

おそらくRectangleの部分の問題だと思います。が分かりませんでした。C#、.NETの情報しか出てきません。

####2.ホバーエフェクトの実装方法__<未解決>__
ホバーエフェクトというかマウスが上にある時に影を3秒ぐらい時間をかけてつけたいです。(ちょうどhtml,cssのデザインのように)日本語、英語で数時間検索してもどのようにすればよいのかわかりません。

####3.dc = ((LPDRAWITEMSTRUCT)(lp))->hDC;や((LPDRAWITEMSTRUCT)(lp))->rcItem.rightの意味が分からない<解決済み>
愚かな質問かもしれません。数日検索して理解しようとしましたがわかりませんでした。

#その他
前回の質問でも迷惑をかけてしまったかもしれません。初心者マークをつけさせていただきました。少しずつ学んでいきたいと思います。よろしくお願いいたします。

#コード全掲

C++

1#include <windows.h> 2#include <cstdio> 3#include <iostream> 4#include <string> 5 6static int width = 0, height = 0; 7 8LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { 9 10 HDC hdc; 11 PAINTSTRUCT ps; 12 13 14 switch (msg) { 15 case WM_DESTROY: 16 PostQuitMessage(0); 17 18 printf("[INFO] Program is about to finish."); 19 20 return 0; 21 22 23 case WM_SIZE: 24 width = LOWORD(lp); 25 height = HIWORD(lp); 26 27 std::cout<<"[INFO] width:"<<width<<"---"; 28 std::cout<<"[INFO] height:"<<height<<"\n"; 29 30 return 0; 31 32 33 case WM_CREATE: 34 CreateWindow( 35 TEXT("BUTTON") , TEXT("U") , 36 WS_CHILD | WS_VISIBLE | BS_OWNERDRAW , 37 0 , 0 , 400 , 400 , 38 hwnd , (HMENU)1 , 39 ((LPCREATESTRUCT)(lp))->hInstance , NULL 40 ); 41 return 0; 42 43 44 case WM_DRAWITEM: 45 hdc = ((LPDRAWITEMSTRUCT)(lp))->hDC; 46 47 if (((LPDRAWITEMSTRUCT)(lp))->itemState & ODS_SELECTED) { 48 SelectObject(hdc, CreateSolidBrush(RGB(80, 91, 109))); 49 std::cout<<"[INFO] ON\n"; 50 }else { 51 SelectObject(hdc, CreateSolidBrush(RGB(73, 147, 120))); 52 std::cout<<"[INFO] OFF\n"; 53 } 54 Rectangle(hdc , 0 , 0 , 55 ((LPDRAWITEMSTRUCT)(lp))->rcItem.right , 56 ((LPDRAWITEMSTRUCT)(lp))->rcItem.bottom 57 ); 58 DeleteObject(SelectObject(hdc , GetStockObject(WHITE_BRUSH))); 59 return TRUE; 60 61 } 62 return DefWindowProc(hwnd , msg , wp , lp); 63} 64 65 66 67int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , 68 PSTR lpCmdLine , int nCmdShow ) { 69 70 printf("[INFO] Program has just started.\n"); 71 72 HWND hwnd; 73 MSG msg; 74 WNDCLASS winc; 75 76 winc.style = CS_HREDRAW | CS_VREDRAW; 77 winc.lpfnWndProc = WndProc; 78 winc.cbClsExtra = winc.cbWndExtra = 0; 79 winc.hInstance = hInstance; 80 winc.hIcon = LoadIcon(NULL , IDI_APPLICATION); 81 winc.hCursor = LoadCursor(NULL , IDC_ARROW); 82 winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 83 winc.lpszMenuName = NULL; 84 winc.lpszClassName = TEXT("U"); 85 86 if (!RegisterClass(&winc)) return -1; 87 88 hwnd = CreateWindow( 89 TEXT("U") , TEXT("U") , 90 WS_OVERLAPPEDWINDOW | WS_VISIBLE , 91 CW_USEDEFAULT , CW_USEDEFAULT , 92 CW_USEDEFAULT , CW_USEDEFAULT , 93 NULL , NULL , hInstance , NULL 94 ); 95 96 if (hwnd == NULL) return -1; 97 98 99 while(GetMessage(&msg , NULL , 0 , 0)) { 100 TranslateMessage(&msg); 101 DispatchMessage(&msg); 102 } 103 104 return msg.wParam; 105}

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

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

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

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

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

t_obara

2019/04/01 06:38

そもそもですが、何故Windows APIを利用するのでしょうか。別にC++の学習でよければ、UIが無いものから作れば良いと思います。どうしてもUIがしたいのであれば、C#からやれば良いのでは無いでしょうか。
uenotokyoline

2019/04/01 07:19

すみません。一度C++でUIのないものの学習は行いました。あとC#はVSで実際に作成したことがあります。
t_obara

2019/04/01 09:08

1、2についてはC#でもわかる様になるはず、3はC++をしていればわかるはずかと。
guest

回答3

0

1.四角形が黒枠がついてしまう<解決済み>

この用途には FillRect を使用します。通常はペンの制御が難しい(※)ため Rectangle 等のペンを使用する描画処理はあまり使われません。角が丸い四角形を描画する際には RoundRect を使用したりするのですが、立体感を持たせるために内側の1ピクセルだけ違う色で描きたい場合に RoundRect では正確には対応できません。RoundRect を使用する場合は内側の色をあらかじめ塗っておいて上書きしたりする手法等が使われます。
※2ピクセル以上の幅のペンは視点と終点が円形になるため、矩形を描くのがめんどくさい。

3.dc = ((LPDRAWITEMSTRUCT)(lp))->hDC;や((LPDRAWITEMSTRUCT)(lp))->rcItem.rightの意味が分からない<解決済み>

iwanote さんの回答通りです。以下のように変換後の型で宣言した変数に入れた方が処理しやすいかと思います。ついでに FillRect に書き換えてあります。

C++

1 case WM_DRAWITEM: 2 LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lp; 3 hdc = pdis->hDC; 4 HBRUSH brush; 5 if (pdis->itemState & ODS_SELECTED) { 6 brush = CreateSolidBrush(RGB(80, 91, 109)); 7 std::cout << "[INFO] on\n"; 8 } 9 else { 10 brush = CreateSolidBrush(RGB(73, 147, 120)); 11 std::cout << "[INFO] off\n"; 12 } 13 FillRect(hdc, 14 &pdis->rcItem, 15 brush 16 ); 17 DeleteObject(brush); 18 return TRUE;

2.ホバーエフェクトの実装方法<未解決>

ボタンの場合、ホバー処理は TrackMouseEvent で検出するのが簡単で良いと思います。現在のオーナー描画と組み合わせて処理を考えるのがけっこうめんどくさい感じはしますね。オーナードローでやる場合、ホバー状態をフラグ変数をどっかに持っておいて、描画は WM_DRAWITEM ですべて処理して、再描画の必要なタイミングで InvalidateRect を呼び出す感じで実装するのがおすすめです。昔は InvalidateRect のちらつきが無視できないレベルでしたが、現在の PC だとそれほど目立たないかと思います。

ちょうどホバーボタンの解説をしているサイトがあったので、参考になるかもしれません。
http://hp.vector.co.jp/authors/VA016117/hoverbtn2.html
このページは 2001 年に記載なので、相当古いものではありますが、Win32 API で実装しようとすると古くなったサイトの方が有益な情報が多いかと思います。とは言っても最新の知識も必要なので難しいところですが。

投稿2019/04/01 17:48

atata0319

総合スコア881

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

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

uenotokyoline

2019/04/02 00:17

ご丁寧な補足ありがとうございました。 とても勉強になります。 また2についてリンク先さっそく参考にさせていただきます。
guest

0

1 rectangleはたしか内側をブラシ、外側をペンで書くのでペンの指定をPS_NULLとかにすればいいと思う
2 ちょっとよくわからないです
3 lpをキャストしてます。(LPDRAWITEMSTRUCT)(lp)->hDCで分けて考えた方がいいかと

投稿2019/04/01 07:09

iwanote

総合スコア295

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

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

uenotokyoline

2019/04/01 07:19

1.3についてわかりました。ありがとうございました。
guest

0

C++

1hpen = CreatePen(PS_SOLID, 5, RGB(73, 147, 120)); 2hbr = CreateSolidBrush(RGB(73, 147, 120)); 3SelectObject(hdc, hpen); 4SelectObject(hdc, hbr);

のようにすることで枠をなくすことに成功しました

投稿2019/04/01 14:37

uenotokyoline

総合スコア15

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問