合計 昨日 今日

C言語でリソースの練習をしています

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: h1j1k1
[URL]
ぴよぴよ(467 ポイント)
Date: 2018年1月11日(木) 22:00
No: 1
(OFFLINE)

 C言語でリソースの練習をしています

C言語でリソースを扱う練習をしているのですが、
Dllにする所はできたのですがDllからロードする方法がわかりません。

コード[C++]: 全て選択
1
2
3
// images.rc
MY_ICON ICON DISCARDABLE ".\\image\\icon.ico"
MY_CURSOR CURSOR DISCARDABLE ".\\image\\cursor.cur"

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// main.c
#include <windows.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
 
#define PROGRAM_NAME "SpyLit"
 
 
HINSTANCE hInstance;
HWND hMainWindow;
 
LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp);
 
LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp){
    HDC hdc;
    PAINTSTRUCT ps;
   
    switch (msg) {
        case WM_DESTROY:{
            PostQuitMessage(0);
            break;
        }
    }
    return DefWindowProc(hwnd , msg , wp , lp);
}
 
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow ) {
   
   
    hInstance = hInst;
    WNDCLASSEX wc;
    PSTR pClassName = TEXT(PROGRAM_NAME);
    PSTR pWindowName = TEXT("MAIN");
   
    wc.cbSize = sizeof(wc);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = LoadIcon(hInstance, TEXT("MY_CURSOR"));
    wc.hIconSm = wc.hIcon;
    wc.hCursor = LoadCursor(hInstance, TEXT("MY_CURSOR"));
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = pClassName;
 
    if (!RegisterClassEx(&wc)) return FALSE;
   
    hMainWindow = CreateWindow(
            wc.lpszClassName, pWindowName,
            WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
            CW_USEDEFAULT , CW_USEDEFAULT ,
            CW_USEDEFAULT , CW_USEDEFAULT ,
            NULL , NULL , hInstance , NULL);
           
    if(hMainWindow == NULL) return FALSE;
   
    MSG msg;
    while(GetMessage(&msg , NULL , 0 , 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

このようにしてるのですが、描画されません。
どうしたらいいでしょうか

Name: maru
[URL]
中級者(14,873 ポイント)
Date: 2018年1月12日(金) 08:03
No: 2
(OFFLINE)

 Re: C言語でリソースの練習をしています

DLLのリソースをロードするにはDLLのインスタンスハンドルを指定する必要があります。
DLLのインスタンスハンドルはLoadLibraryEx関数で取得します。

Name: Bull
[URL]
初心者(7,221 ポイント)
Date: 2018年1月12日(金) 08:13
No: 3
(OFFLINE)

 Re: C言語でリソースの練習をしています

LoadIcon と LoadCursor をする時に、EXE のインスタンスハンドルを指定しているからでしょう。
LoadLibrary でDLL のインスタンスハンドルを取得し、それを指定すれば良いと思います。

リソースのみの DLL の作成
を参考にしてみて下さい。

Name: naohiro19
[URL]
プログラマー(36,169 ポイント)
Date: 2018年1月12日(金) 08:23
No: 4
(OFFLINE)

 Re: C言語でリソースの練習をしています

C++の<memory> というヘッダを使ってスコープから外れると自動的に解放してくれる std::unique_ptr を使います。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
#include <memory>
#include <type_traits>
#include <cassert>
#include <Windows.h>
 
void DllCloser(HMODULE hmodule) {
    assert(hmodule);
    FreeLibrary(hmodule);
}
std::unique_ptr<std::remove_pointer<HMODULE>::type, decltype(&DllCloser)>
        dll(LoadLibraryA("****.dll"), DllCloser);


DLLのハンドルを取得するには dll.get() と書くだけでそのDLLのハンドルを取得できます。また GetProcAddress(dll.get(), "関数名"); と渡すことでその関数ポインタのアドレスも取得ができます。
なお、DllCloser関数内で assertを書いているのは DLLのハンドルが nullでないことをあらわすためですので書いておけばOKです。

Name: h1j1k1
[URL]
ぴよぴよ(467 ポイント)
Date: 2018年1月12日(金) 18:22
No: 5
(OFFLINE)

 Re: C言語でリソースの練習をしています

maruさんBullさんnaohiro19さん素早い返信ありがとうございます

maruさん>>
dllはコンパイルに入れるだけではなく、ハンドルを取得しなければいけないのですね。
ありがとうございます!

Bullさん>>
このサイトは前も見たのですが、下のほうに使用方法も乗ってたんですね。
見落としてましたすいません

naohiro19さん>>
ソースまで載せていただきありがとうございます...といいたいところなのですが、
C言語で勉強しているので....申し訳ございません!


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[25人]