QuickDocumentDialog::QuickDocumentDialog(QWidget *parent, const char *name) :QDialog(parent) { setWindowTitle(name); setModal(true); ui.setupUi(this); connect(ui.pushButtonClass , SIGNAL(clicked()), SLOT(addUserClass())); ui.comboBoxSize->addItem("10pt"); ui.comboBoxSize->addItem("11pt"); ui.comboBoxSize->addItem("12pt"); connect(ui.pushButtonPaper , SIGNAL(clicked()), SLOT(addUserPaper())); connect(ui.pushButtonEncoding , SIGNAL(clicked()), SLOT(addUserEncoding())); connect(ui.pushButtonOptions , SIGNAL(clicked()), SLOT(addUserOptions())); ui.listWidgetOptions->setSelectionMode(QAbstractItemView::ExtendedSelection); setWindowTitle(tr("Quick Start")); }
bool startJVM(TCHAR* basedir, TCHAR* appFolder, TCHAR* jar, int argCount, LPTSTR *szArgList) { TCHAR jvmPath[LAUNCHER_MAXPATH+1] = {0}; JavaVMInitArgs jvmArgs; JavaVMOption options[MAX_OPTIONS+1]; JVM_CREATE createProc; JNIEnv* env; JavaVM* jvm = NULL; char jarASCII[LAUNCHER_MAXPATH] = {0}; char classpath[LAUNCHER_MAXPATH*2] = {0}; char mainclassASCII[LAUNCHER_MAXPATH] = {0}, appClasspath[LAUNCHER_MAXPATH] = {0}; size_t outlen = 0; jclass cls; jmethodID mid; TCHAR argname[MAX_OPTION_NAME + 1] = {0}; TCHAR argvalue[LAUNCHER_MAXPATH] = {0}, mainclass[LAUNCHER_MAXPATH] = {0}; CHAR argvalueASCII[LAUNCHER_MAXPATH] = {0}; HMODULE msvcrtdll; bool runtimeBundled; TCHAR tmpPath[LAUNCHER_MAXPATH] = {0}; TCHAR appid[LAUNCHER_MAXPATH] = {0}; memset(&options, 0, sizeof(JavaVMOption)*(MAX_OPTIONS + 1)); memset(&jvmArgs, 0, sizeof(JavaVMInitArgs)); makeFullFileName(basedir, _T("\\runtime"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR)); runtimeBundled = fileExists(tmpPath); if (runtimeBundled) { if (!getJvmPath(basedir, jvmPath, LAUNCHER_MAXPATH)) { showError(_T("jvm.dll is not found in bundled runtime."), jvmPath); return false; } //make sure msvcr100 is loaded (or we may fail if copy of it is not installed into system) makeFullFileName(basedir, _T("runtime\\jre\\bin\\msvcr100.dll"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR)); msvcrtdll = ::LoadLibrary(tmpPath); } else { if (!getSystemJvmPath(jvmPath, LAUNCHER_MAXPATH)) { showError(_T("No bundled runtime and can not find system JRE."), jvmPath); return false; } //make sure msvcr100 is loaded (or we may fail if copy of it is not installed into system) makeFullFileName(basedir, _T("\\bin\\msvcr100.dll"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR)); msvcrtdll = ::LoadLibrary(tmpPath); } // Dynamically load the JVM HMODULE jvmLibHandle = LoadLibrary(jvmPath); if (jvmLibHandle == NULL) { DWORD dwErr = GetLastError(); showError(_T("Error loading jvm.dll"), jvmPath); return false; } //convert argument to ASCII string as this is what CreateJVM needs wcstombs_s(&outlen, jarASCII, LAUNCHER_MAXPATH, jar, (size_t) wcslen(jar) + 1); strcpy_s(classpath, LAUNCHER_MAXPATH*2, "-Djava.class.path="); strcat_s(classpath, LAUNCHER_MAXPATH, jarASCII); if (getConfigValue(basedir, CONFIG_CLASSPATH_KEY, argvalue, LAUNCHER_MAXPATH)) { size_t inLen = (size_t) wcslen(argvalue); //convert argument to ASCII string as this is what CreateJVM needs wcstombs_s(&outlen, argvalueASCII, sizeof(argvalueASCII), argvalue, inLen + 1); //compress spaces and replaces them with ; { char *in = argvalueASCII; char *out = argvalueASCII; bool needSemicolon = false; while (*in != 0) { if (*in == ' ') { if (needSemicolon) { *out = ';'; out++; needSemicolon = false; } } else { needSemicolon = true; *out = *in; out++; } in++; } *out = 0; } if (strlen(argvalueASCII) > 0) { strcat_s(classpath, LAUNCHER_MAXPATH, ";"); strcat_s(classpath, LAUNCHER_MAXPATH, argvalueASCII); } } // Set up the VM init args jvmArgs.version = JNI_VERSION_1_2; options[0].optionString = _strdup(classpath); int cnt = 1; if (isDebug) { options[cnt].optionString = _strdup("vfprintf"); options[cnt].extraInfo = vfprintfHook; cnt++; } //Note: should not try to quote the path. Spaces are fine here _stprintf_s(argvalue, _T("-Djava.library.path=%s"), appFolder); wcstombs_s(&outlen, argvalueASCII, sizeof(argvalueASCII), argvalue, wcslen(argvalue) + 1); options[cnt].optionString = _strdup(argvalueASCII); cnt++; //add app specific JVM parameters int idx = 1; int found = 0; do { _stprintf_s(argname, MAX_OPTION_NAME, _T("jvmarg.%d"), idx); found = getConfigValue(basedir, argname, argvalue, LAUNCHER_MAXPATH); if (found) { TCHAR* option = replaceStr(argvalue, _T("$APPDIR"), basedir); char* jvmOption = convertToDupedChar(option); if (jvmOption != NULL) { options[cnt].optionString = jvmOption; cnt++; } idx++; } } while (found && idx < MAX_OPTIONS); cnt = addUserOptions(basedir, options, cnt); jvmArgs.version = 0x00010002; jvmArgs.options = options; jvmArgs.nOptions = cnt; jvmArgs.ignoreUnrecognized = JNI_TRUE; // Create the JVM // NB: need to use ASCII string as UNICODE is not supported createProc = (JVM_CREATE) GetProcAddress(jvmLibHandle, "JNI_CreateJavaVM"); if (createProc == NULL) { showError(_T("Failed to locate JNI_CreateJavaVM"), jvmPath); return false; } if ((*createProc)(&jvm, &env, &jvmArgs) < 0) { showError(_T("Failed to create JVM"), jvmPath); return false; } if (!getConfigValue(basedir, CONFIG_MAINCLASS_KEY, mainclass, LAUNCHER_MAXPATH)) { showError(_T("Package error"), _T("No main class specified. Nothing to launch")); return false; } else { size_t inLen = (size_t) wcslen(mainclass); //convert argument to ASCII string as this is what CreateJVM needs wcstombs_s(&outlen, mainclassASCII, sizeof(mainclassASCII), mainclass, inLen + 1); } cls = env->FindClass(mainclassASCII); if (cls != NULL) { mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); if (mid != NULL) { jclass stringClass = env->FindClass("java/lang/String"); //prepare app arguments if any. Skip value at index 0 - this is path to executable ... //NOTE: // - what if user run in non-English/UTF-8 locale? do we need to convert args? // - extend to pass jvm args and debug args (allow them in front, use marker option to separate them?) int startArgIndex = countNumberOfSystemArguments(argCount, szArgList); jobjectArray args = env->NewObjectArray(argCount - startArgIndex, stringClass, NULL); for(int i=startArgIndex; i<argCount; i++) { size_t inLen = (size_t) wcslen(szArgList[i]); env->SetObjectArrayElement(args, i-startArgIndex, env->NewString((jchar*)szArgList[i], inLen)); } env->CallStaticVoidMethod(cls, mid, args); } else { showError(_T("no main method in the main class!"), mainclass); return false; } } else { showError(_T("no main class."), mainclass); return false; } if (env->ExceptionOccurred()) { showError(_T("Failed due to exception from main class."), mainclass); env->ExceptionDescribe(); } // If application main() exits quickly but application is run on some other thread // (e.g. Swing app performs invokeLater() in main and exits) // then if we return execution to tWinMain it will exit. // This will cause process to exit and application will not actually run. // // To avoid this we are trying to detach jvm from current thread (java.exe does the same) // Because we are doing this on the main JVM thread (i.e. one that was used to create JVM) // this call will spawn "Destroy Java VM" java thread that will shut JVM once there are // no non-daemon threads running, and then return control here. // I.e. this will happen when EDT and other app thread will exit. if (jvm->DetachCurrentThread() != 0) { showError(_T("Detach failed."), NULL); } jvm->DestroyJavaVM(); return true; }