编译为.dll时菜单项不起作用

时间:2015-03-25 04:43:48

标签: c++ win32gui

我有这种奇怪的行为,当我使用JNI编译和运行时,我的代码无法调用事件处理程序,但如果我在VS 2013中将其编译为.exe,则会有效。

案例ID_KRUSKAL_IMPERFECT,案例ID_KRUSKAL_PERFECT,案例ID_PRIM_IMPERFECT,案例ID_PRIM_PERFECT列出了不工作的案例。这种情况是菜单(见下图)。在右边,它会弹出另一个对话框

enter image description here

然而,当我点击案例ID_FILE_EXIT时窗口关闭(因此它适用于此按钮)

Source code as attached :
#include <windows.h>
#include <iostream>
#include <string>
#include <fstream>
//#include "resource.h"
#include "maze.h"
#include <sstream>
#include <vector>
#include "HelloWorld.h"
#include "win_main.h"
#include "KruskalAlgo.h"
#include "PrimAlgo.h"

//JNI
#include <jni.h>
#include <stdio.h>
#include "Window.h"

//win32 GUI ID
#define IDR_MENU1                       102
#define IDI_ICON1                       103
#define IDD_DIALOG1                     105
#define IDC_EDIT1                       1005
#define IDC_WIDTH                       1005
#define IDC_EDIT2                       1006
#define IDC_EDIT3                       1007
#define IDC_WALLBUTTON                  1008
#define IDC_PATHBUTTON                  1009
#define IDC_EDIT4                       1010
#define IDC_HEIGHT                      1010
#define ID_STUFF_GO                     40001
#define ID_FILE_EXIT                    40002
#define ID_FILE_GENERATEMAZE            40003
#define ID_FILE_UPLOADMAZE              40004
#define ID_GENERATEMAZE_KRUSKAL         40005
#define ID_GENERATEMAZE_PRIM            40006
#define ID_GENERATEMAZE_KRUSKAL40007    40007
#define ID_GENERATEMAZE_PRIM40008       40008
#define ID_GENERATEMANUALLY_KRUSKAL     40009
#define ID_GENERATEMANUALLY_PRIM        40010
#define ID_KRUSKAL_PERFECT              40011
#define ID_KRUSKAL_IMPERFECT            40012
#define ID_PRIM_PERFECT                 40013
#define ID_PRIM_IMPERFECT               40014
#define ID_GENERATEMAZEAUTO             40015
//class name
LPCSTR g_szClassName = "mazeGenerator";

//2d vector to store 1s and 0s
typedef std::vector<std::vector<int>> IntMatrix;
IntMatrix vector2D;

//function header
void drawMaze(HWND hwnd);
void fileUpload(HWND hwnd);
void chooseColour(HWND hwnd);

//global height
int inRowCount;
//global width
int inColCount;

int disp;

PrimAlgo p;
PrimAlgo pi;
KruskalAlgo k;
KruskalAlgo ki;




INT_PTR CALLBACK ConfigDialog(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{

    //HWND hWndComboBox;
    switch (Message)
    {
    case WM_INITDIALOG:

        return TRUE;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDC_WALLBUTTON:
            chooseColour(hwnd);
            break;

        case IDC_PATHBUTTON:
            chooseColour(hwnd);
            break;

        case IDOK:
            inColCount = GetDlgItemInt(hwnd, IDC_WIDTH, NULL, FALSE);
            inRowCount = GetDlgItemInt(hwnd, IDC_HEIGHT, NULL, FALSE);
            EndDialog(hwnd, IDD_DIALOG1);

            break;

        case IDCANCEL:
            EndDialog(hwnd, IDD_DIALOG1);
            break;
        default:
            return FALSE;
        }
    default:
        return FALSE;
    }
    return TRUE;
}

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HWND temp;
    HINSTANCE htemp;
    switch (msg)
    {
    case WM_CREATE:
    {
        //initialization
        HMENU hMenu, hSubMenu1, hSubMenu2, hSubMenu3, hSubMenu4, hSubMenu5;
        HICON hIcon, hIconSm;


        //menu
        hMenu = CreateMenu();
        hSubMenu1 = CreatePopupMenu();
        hSubMenu2 = CreatePopupMenu();
        hSubMenu3 = CreatePopupMenu();
        hSubMenu4 = CreatePopupMenu();
        hSubMenu5 = CreatePopupMenu();

        AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu1, "&File");

        AppendMenu(hSubMenu1, MF_STRING | MF_POPUP, (UINT)hSubMenu2, "&New Game");

        AppendMenu(hSubMenu2, MF_STRING, ID_GENERATEMAZEAUTO, "&Generate Automatically");
        AppendMenu(hSubMenu2, MF_STRING | MF_POPUP, (UINT)hSubMenu3, "&Generate Manually");

        AppendMenu(hSubMenu3, MF_STRING | MF_POPUP, (UINT)hSubMenu4, "&Kruskal");

        AppendMenu(hSubMenu4, MF_STRING, ID_KRUSKAL_PERFECT, "&Perfect");
        AppendMenu(hSubMenu4, MF_STRING, ID_KRUSKAL_IMPERFECT, "&Imperfect");

        AppendMenu(hSubMenu3, MF_STRING | MF_POPUP, (UINT)hSubMenu5, "&Prim's");

        AppendMenu(hSubMenu5, MF_STRING, ID_KRUSKAL_PERFECT, "&Perfect");
        AppendMenu(hSubMenu5, MF_STRING, ID_KRUSKAL_IMPERFECT, "&Imperfect");



        AppendMenu(hSubMenu1, MF_STRING, ID_FILE_EXIT, "&Exit");



        /*hSubMenu = CreatePopupMenu();
        AppendMenu(hSubMenu, MF_STRING, ID_STUFF_GO, "&Go");
        AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Stuff");*/

        SetMenu(hwnd, hMenu);


        hIcon = (HICON)LoadImage(NULL, "logo.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
        if (hIcon)
            SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
        else
            MessageBox(hwnd, "Could not load large icon!", "Error", MB_OK | MB_ICONERROR);

        hIconSm = (HICON)LoadImage(NULL, "logo.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
        if (hIconSm)
            SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
        else
            MessageBox(hwnd, "Could not load small icon!", "Error", MB_OK | MB_ICONERROR);
    }

        break;
    case WM_PAINT:
    {
        drawMaze(hwnd);

    }
        break;


    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case ID_FILE_EXIT:
            PostMessage(hwnd, WM_CLOSE, 0, 0);
            break;
        case ID_GENERATEMAZEAUTO:
            fileUpload(hwnd);
            InvalidateRect(hwnd, 0, TRUE);
            SetWindowPos(hwnd, 0, 0, 0, (inColCount * 10) + 17, (inRowCount * 10) + 60, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
            break;
        case ID_PRIM_PERFECT:
            disp = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), hwnd, ConfigDialog);

            p.setDimension(inRowCount, inColCount);
            p.setWallPath(0, 1);
            p.generateMaze();
            vector2D = p.get2DOutput();
            InvalidateRect(hwnd, 0, TRUE);
            SetWindowPos(hwnd, 0, 0, 0, (inColCount * 10) + 17, (inRowCount * 10) + 60, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
            break;
        case ID_PRIM_IMPERFECT:
            disp = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), hwnd, ConfigDialog);

            pi.setDimension(inRowCount, inColCount);
            pi.setWallPath(0, 1);
            pi.generateMaze();
            pi.generateImperfect();
            vector2D = pi.get2DOutput();
            InvalidateRect(hwnd, 0, TRUE);
            SetWindowPos(hwnd, 0, 0, 0, (inColCount * 10) + 17, (inRowCount * 10) + 60, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
            break;
        case ID_KRUSKAL_PERFECT:
            disp = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), hwnd, ConfigDialog);
            k.setDimension(inRowCount, inColCount);
            k.setWallPath(0, 1);
            k.generateMaze();
            vector2D = k.get2DOutput();
            InvalidateRect(hwnd, 0, TRUE);
            SetWindowPos(hwnd, 0, 0, 0, (inColCount * 10) + 17, (inRowCount * 10) + 60, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);

            break;
        case ID_KRUSKAL_IMPERFECT:
            disp = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), hwnd, ConfigDialog);

            ki.setDimension(inRowCount, inColCount);
            ki.setWallPath(0, 1);
            ki.generateMaze();
            ki.generateImperfect();
            vector2D = ki.get2DOutput();
            InvalidateRect(hwnd, 0, TRUE);
            SetWindowPos(hwnd, 0, 0, 0, (inColCount * 10) + 17, (inRowCount * 10) + 60, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
            break;



        }


        break;
    case WM_CLOSE:
    {
        DestroyWindow(hwnd);
        break;
    }
    case WM_DESTROY:
    {

        PostQuitMessage(0);
        break;
    }
    default:
    {
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    }
    return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
    wc.lpszClassName = g_szClassName;
    wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
    wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);

    if (!RegisterClassEx(&wc))
    {
        MessageBoxA(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window

    hwnd = CreateWindowEx(
        WS_EX_WINDOWEDGE,
        g_szClassName,
        "Maze Generator 0.1",
        WS_OVERLAPPEDWINDOW,
        0, 0, 300, 60,
        NULL, NULL, hInstance, NULL);

    if (hwnd == NULL)
    {
        MessageBoxA(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while (GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

//draws maze based on vector2D
void chooseColour(HWND hwnd){
    CHOOSECOLOR cc;                 // common dialog box structure 
    static COLORREF acrCustClr[16]; // array of custom colors 
    HBRUSH hbrush;                  // brush handle
    static DWORD rgbCurrent;        // initial color selection
    ZeroMemory(&cc, sizeof(cc));
    cc.lStructSize = sizeof(cc);
    cc.hwndOwner = hwnd;
    cc.lpCustColors = (LPDWORD)acrCustClr;
    cc.rgbResult = rgbCurrent;
    cc.Flags = CC_FULLOPEN | CC_RGBINIT;

    if (ChooseColor(&cc) == TRUE)
    {
        hbrush = CreateSolidBrush(cc.rgbResult);
        rgbCurrent = cc.rgbResult;
    }
}
void drawMaze(HWND hwnd){
    RECT rcClient;
    GetClientRect(hwnd, &rcClient);
    PAINTSTRUCT ps;
    //starting x and y value for first maze cell
    int startRow = 0;
    int startCol = 0;
    //displacement
    int dRow = 10;
    int dCol = 10;
    //counter
    int rowCounter = 0;
    int colCounter = 0;

    HDC hdc = BeginPaint(hwnd, &ps);
    FillRect(hdc, &rcClient, (HBRUSH)GetStockObject(LTGRAY_BRUSH));
    for (int rowId = 0; rowId < inRowCount; rowId++){
        for (int colId = 0; colId < inColCount; colId++){
            if (vector2D[rowId][colId] == 1){
                RECT cell = { startCol, startRow, startCol + dCol, startRow + dRow };
                FillRect(hdc, &cell, (HBRUSH)GetStockObject(WHITE_BRUSH));

            }
            if (vector2D[rowId][colId] == 0){
                RECT cell = { startCol, startRow, startCol + dCol, startRow + dRow };
                FillRect(hdc, &cell, (HBRUSH)GetStockObject(BLACK_BRUSH));

            }
            startCol += dCol;
            colCounter++;
            if (colCounter == inColCount)
            {
                startCol = 0;
                colCounter = 0;
            }
        }
        startRow += dRow;
        rowCounter++;
        if (rowCounter == inRowCount)
        {
            startRow = 0;
            rowCounter = 0;
        }
    }
    EndPaint(hwnd, &ps);

}

void fileUpload(HWND hwnd){
    //file upload
    OPENFILENAME ofn;
    HANDLE hFile;
    DWORD dwRead;
    char filechar[20000] = "";
    int countMaze = 0;
    int countValue = 0;
    int x = 0;
    int y = 0;
    int tempx = 0;
    int tempy = 0;
    char szFileName[MAX_PATH] = "";

    ZeroMemory(&ofn, sizeof(ofn));

    ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW

    ofn.hwndOwner = hwnd;
    ofn.lpstrFilter = (LPCSTR)"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
    ofn.lpstrFile = (LPSTR)szFileName;
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    ofn.lpstrDefExt = (LPCSTR)"txt";

    if (GetOpenFileName(&ofn))
    {
        // Load the file name for maze drawing
        // Load the file name for maze drawing
        //MessageBox(hWnd, (LPCWSTR)szFileName, (LPCWSTR)L"Notice",MB_OK | MB_ICONINFORMATION);
        hFile = CreateFile((LPCSTR)szFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        ReadFile(hFile, filechar, sizeof(filechar), &dwRead, NULL);
        int status = 1;//to track invalid input detected in the readfile

        while (dwRead != countMaze)
        {
            char temp;

            //temp in ASCII value (convert to 0 and 1)
            temp = *&filechar[countMaze];
            if (temp != '\r' && temp != '\n' && temp != '0' && temp != '1')
            {
                status = 0;
                break;
            }

            if (temp == '\r')//For carriage return case.
            {
                countMaze = countMaze + 1;
                continue;
            }
            if (temp == '\n')//For newline case.
            {
                y = dwRead / (x + 2);
                break;
            }
            x = x + 1;
            countMaze = countMaze + 1;
        }


        //return the width and height needed to print maze.
        if (status == 1){
            inColCount = x;
            inRowCount = y;
            //resize maze based on x and y values.
            vector2D.resize(y);
            for (int i = 0; i < y; i++){
                vector2D[i].resize(x);
            }


            while (dwRead > countValue)
            {
                char temp;
                //temp in ASCII value
                temp = *&filechar[countValue];
                if (temp)

                    if (temp == '\r')//For carriage return case.
                    {
                    countValue++;
                    continue;
                    }
                if (temp == '\n')//For newline case.
                {
                    countValue++;
                    tempx++;
                    tempy = 0;
                    continue;
                }
                //minus 48 to convert from ascii value to integer
                vector2D[tempx][tempy] = int(temp - 48);
                tempy = tempy + 1;
                countValue++;
            }
        }
        else{
            MessageBox(hwnd, (LPCSTR)"Invalid maze file found ! Re-upload please with text file containing 0 and 1 only please", (LPCSTR)"Notice",
                MB_OK | MB_ICONINFORMATION);
        }
        if (status == 1){
            //close hFile handler
            CloseHandle(hFile);

        } 
    }


}


// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT void JNICALL Java_Window_load(JNIEnv *env, jobject thisObj) {
    WinMain(0,0,0,1);
    printf("Hello World!\n");
    return;
}

1 个答案:

答案 0 :(得分:0)

它不起作用,因为传递给WinMain的hInstance在Java_Window_load()中为NULL。您需要使用DLL的HINSTANCE,否则菜单中的资源将无效。

做这样的事情:

static HINSTANCE sDllInstance;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
  if (fdwReason == DLL_PROCESS_ATTACH) { 
    sDllInstance = hinstDLL;
  }
  return TRUE;
}

// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT void JNICALL Java_Window_load(JNIEnv *env, jobject thisObj) {
    WinMain(sDllInstance,0,0,1);
    printf("Hello World!\n");
    return;
}