我有这种奇怪的行为,当我使用JNI编译和运行时,我的代码无法调用事件处理程序,但如果我在VS 2013中将其编译为.exe,则会有效。
案例ID_KRUSKAL_IMPERFECT,案例ID_KRUSKAL_PERFECT,案例ID_PRIM_IMPERFECT,案例ID_PRIM_PERFECT列出了不工作的案例。这种情况是菜单(见下图)。在右边,它会弹出另一个对话框
然而,当我点击案例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;
}
答案 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;
}