1 /* 2 * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "awt.h" 27 #include "awt_FileDialog.h" 28 #include "awt_Dialog.h" 29 #include "awt_Toolkit.h" 30 #include "ComCtl32Util.h" 31 #include <commdlg.h> 32 #include <cderr.h> 33 #include <shlobj.h> 34 35 36 /************************************************************************ 37 * AwtFileDialog fields 38 */ 39 40 /* WFileDialogPeer ids */ 41 jfieldID AwtFileDialog::parentID; 42 jfieldID AwtFileDialog::fileFilterID; 43 jmethodID AwtFileDialog::setHWndMID; 44 jmethodID AwtFileDialog::handleSelectedMID; 45 jmethodID AwtFileDialog::handleCancelMID; 46 jmethodID AwtFileDialog::checkFilenameFilterMID; 47 jmethodID AwtFileDialog::isMultipleModeMID; 48 49 /* FileDialog ids */ 50 jfieldID AwtFileDialog::modeID; 51 jfieldID AwtFileDialog::dirID; 52 jfieldID AwtFileDialog::fileID; 53 jfieldID AwtFileDialog::filterID; 54 55 /* Localized filter string */ 56 #define MAX_FILTER_STRING 128 57 static TCHAR s_fileFilterString[MAX_FILTER_STRING]; 58 /* Non-localized suffix of the filter string */ 59 static const TCHAR s_additionalString[] = TEXT(" (*.*)\0*.*\0"); 60 61 // Default limit of the output buffer. 62 #define SINGLE_MODE_BUFFER_LIMIT MAX_PATH+1 63 #define MULTIPLE_MODE_BUFFER_LIMIT 32768 64 65 // The name of the property holding the pointer to the OPENFILENAME structure. 66 static LPCTSTR OpenFileNameProp = TEXT("AWT_OFN"); 67 68 /***********************************************************************/ 69 70 void 71 AwtFileDialog::Initialize(JNIEnv *env, jstring filterDescription) 72 { 73 int length = env->GetStringLength(filterDescription); 74 DASSERT(length + 1 < MAX_FILTER_STRING); 75 LPCTSTR tmp = JNU_GetStringPlatformChars(env, filterDescription, NULL); 76 _tcscpy_s(s_fileFilterString, MAX_FILTER_STRING, tmp); 77 JNU_ReleaseStringPlatformChars(env, filterDescription, tmp); 78 79 //AdditionalString should be terminated by two NULL characters (Windows 80 //requirement), so we have to organize the following cycle and use memcpy 81 //unstead of, for example, strcat. 82 LPTSTR s = s_fileFilterString; 83 while (*s) { 84 ++s; 85 DASSERT(s < s_fileFilterString + MAX_FILTER_STRING); 86 } 87 DASSERT(s + sizeof(s_additionalString) < s_fileFilterString + MAX_FILTER_STRING); 88 memcpy(s, s_additionalString, sizeof(s_additionalString)); 89 } 90 91 LRESULT CALLBACK FileDialogWndProc(HWND hWnd, UINT message, 92 WPARAM wParam, LPARAM lParam) 93 { 94 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 95 96 switch (message) { 97 case WM_COMMAND: { 98 if (LOWORD(wParam) == IDCANCEL) 99 { 100 // Unlike Print/Page dialogs, we only handle IDCANCEL here and 101 // don't handle IDOK. This is because user can press OK button 102 // when no file is selected, and the dialog is not closed. So 103 // OK button is handled in the CDN_FILEOK notification handler 104 // (see FileDialogHookProc below) 105 jobject peer = (jobject)(::GetProp(hWnd, ModalDialogPeerProp)); 106 env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong)0); 107 } 108 break; 109 } 110 } 111 112 WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp)); 113 return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam); 114 } 115 116 static UINT_PTR CALLBACK 117 FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) 118 { 119 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 120 121 TRY; 122 123 HWND parent = ::GetParent(hdlg); 124 125 switch(uiMsg) { 126 case WM_INITDIALOG: { 127 OPENFILENAME *ofn = (OPENFILENAME *)lParam; 128 jobject peer = (jobject)(ofn->lCustData); 129 env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, 130 (jlong)parent); 131 ::SetProp(parent, ModalDialogPeerProp, reinterpret_cast<HANDLE>(peer)); 132 133 // fix for 4508670 - disable CS_SAVEBITS 134 DWORD style = ::GetClassLong(hdlg,GCL_STYLE); 135 ::SetClassLong(hdlg,GCL_STYLE,style & ~CS_SAVEBITS); 136 137 // set appropriate icon for parentless dialogs 138 jobject awtParent = env->GetObjectField(peer, AwtFileDialog::parentID); 139 if (awtParent == NULL) { 140 ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_BIG, 141 (LPARAM)AwtToolkit::GetInstance().GetAwtIcon()); 142 } else { 143 env->DeleteLocalRef(awtParent); 144 } 145 146 // subclass dialog's parent to receive additional messages 147 WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(parent, 148 FileDialogWndProc); 149 ::SetProp(parent, NativeDialogWndProcProp, reinterpret_cast<HANDLE>(lpfnWndProc)); 150 151 ::SetProp(parent, OpenFileNameProp, (void *)lParam); 152 153 break; 154 } 155 case WM_DESTROY: { 156 HIMC hIMC = ::ImmGetContext(hdlg); 157 if (hIMC != NULL) { 158 ::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0); 159 ::ImmReleaseContext(hdlg, hIMC); 160 } 161 162 WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(parent, NativeDialogWndProcProp)); 163 ComCtl32Util::GetInstance().UnsubclassHWND(parent, 164 FileDialogWndProc, 165 lpfnWndProc); 166 ::RemoveProp(parent, ModalDialogPeerProp); 167 ::RemoveProp(parent, NativeDialogWndProcProp); 168 ::RemoveProp(parent, OpenFileNameProp); 169 break; 170 } 171 case WM_NOTIFY: { 172 OFNOTIFYEX *notifyEx = (OFNOTIFYEX *)lParam; 173 if (notifyEx) { 174 jobject peer = (jobject)(::GetProp(parent, ModalDialogPeerProp)); 175 if (notifyEx->hdr.code == CDN_INCLUDEITEM) { 176 LPITEMIDLIST pidl = (LPITEMIDLIST)notifyEx->pidl; 177 // Get the filename and directory 178 TCHAR szPath[MAX_PATH]; 179 if (!::SHGetPathFromIDList(pidl, szPath)) { 180 return TRUE; 181 } 182 jstring strPath = JNU_NewStringPlatform(env, szPath); 183 if (strPath == NULL) { 184 throw std::bad_alloc(); 185 } 186 // Call FilenameFilter.accept with path and filename 187 UINT uRes = (env->CallBooleanMethod(peer, 188 AwtFileDialog::checkFilenameFilterMID, strPath) == JNI_TRUE); 189 env->DeleteLocalRef(strPath); 190 return uRes; 191 } else if (notifyEx->hdr.code == CDN_FILEOK) { 192 // This notification is sent when user selects some file and presses 193 // OK button; it is not sent when no file is selected. So it's time 194 // to unblock all the windows blocked by this dialog as it will 195 // be closed soon 196 env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong)0); 197 } else if (notifyEx->hdr.code == CDN_SELCHANGE) { 198 // reallocate the buffer if the buffer is too small 199 LPOPENFILENAME lpofn = (LPOPENFILENAME)GetProp(parent, OpenFileNameProp); 200 201 UINT nLength = CommDlg_OpenSave_GetSpec(parent, NULL, 0) + 202 CommDlg_OpenSave_GetFolderPath(parent, NULL, 0); 203 204 if (lpofn->nMaxFile < nLength) 205 { 206 // allocate new buffer 207 LPTSTR newBuffer = new TCHAR[nLength]; 208 209 if (newBuffer) { 210 memset(newBuffer, 0, nLength * sizeof(TCHAR)); 211 LPTSTR oldBuffer = lpofn->lpstrFile; 212 lpofn->lpstrFile = newBuffer; 213 lpofn->nMaxFile = nLength; 214 // free the previously allocated buffer 215 if (oldBuffer) { 216 delete[] oldBuffer; 217 } 218 219 } 220 } 221 } 222 } 223 break; 224 } 225 } 226 227 return FALSE; 228 229 CATCH_BAD_ALLOC_RET(TRUE); 230 } 231 232 void 233 AwtFileDialog::Show(void *p) 234 { 235 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 236 jobject peer; 237 LPTSTR fileBuffer = NULL; 238 LPTSTR currentDirectory = NULL; 239 jint mode = 0; 240 BOOL result = FALSE; 241 DWORD dlgerr; 242 jstring directory = NULL; 243 jstring title = NULL; 244 jstring file = NULL; 245 jobject fileFilter = NULL; 246 jobject target = NULL; 247 jobject parent = NULL; 248 AwtComponent* awtParent = NULL; 249 jboolean multipleMode = JNI_FALSE; 250 251 OPENFILENAME ofn; 252 memset(&ofn, 0, sizeof(ofn)); 253 254 /* 255 * There's a situation (see bug 4906972) when InvokeFunction (by which this method is called) 256 * returnes earlier than this method returnes. Probably it's caused due to ReplyMessage system call. 257 * So for the avoidance of this mistiming we need to make new global reference here 258 * (not local as it's used by the hook) and then manage it independently of the calling thread. 259 */ 260 peer = env->NewGlobalRef((jobject)p); 261 262 try { 263 DASSERT(peer); 264 target = env->GetObjectField(peer, AwtObject::targetID); 265 parent = env->GetObjectField(peer, AwtFileDialog::parentID); 266 if (parent != NULL) { 267 awtParent = (AwtComponent *)JNI_GET_PDATA(parent); 268 } 269 // DASSERT(awtParent); 270 title = (jstring)(env)->GetObjectField(target, AwtDialog::titleID); 271 HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL; 272 273 if (title == NULL || env->GetStringLength(title)==0) { 274 title = JNU_NewStringPlatform(env, L" "); 275 if (title == NULL) { 276 throw std::bad_alloc(); 277 } 278 } 279 280 JavaStringBuffer titleBuffer(env, title); 281 directory = 282 (jstring)env->GetObjectField(target, AwtFileDialog::dirID); 283 JavaStringBuffer directoryBuffer(env, directory); 284 285 multipleMode = env->CallBooleanMethod(peer, AwtFileDialog::isMultipleModeMID); 286 287 UINT bufferLimit; 288 if (multipleMode == JNI_TRUE) { 289 bufferLimit = MULTIPLE_MODE_BUFFER_LIMIT; 290 } else { 291 bufferLimit = SINGLE_MODE_BUFFER_LIMIT; 292 } 293 LPTSTR fileBuffer = new TCHAR[bufferLimit]; 294 memset(fileBuffer, 0, bufferLimit * sizeof(TCHAR)); 295 296 file = (jstring)env->GetObjectField(target, AwtFileDialog::fileID); 297 if (file != NULL) { 298 LPCTSTR tmp = JNU_GetStringPlatformChars(env, file, NULL); 299 _tcsncpy(fileBuffer, tmp, bufferLimit - 2); // the fileBuffer is double null terminated string 300 JNU_ReleaseStringPlatformChars(env, file, tmp); 301 } else { 302 fileBuffer[0] = _T('\0'); 303 } 304 305 ofn.lStructSize = sizeof(ofn); 306 ofn.lpstrFilter = s_fileFilterString; 307 ofn.nFilterIndex = 1; 308 /* 309 Fix for 6488834. 310 To disable Win32 native parent modality we have to set 311 hwndOwner field to either NULL or some hidden window. For 312 parentless dialogs we use NULL to show them in the taskbar, 313 and for all other dialogs AwtToolkit's HWND is used. 314 */ 315 if (awtParent != NULL) 316 { 317 ofn.hwndOwner = AwtToolkit::GetInstance().GetHWnd(); 318 } 319 else 320 { 321 ofn.hwndOwner = NULL; 322 } 323 ofn.lpstrFile = fileBuffer; 324 ofn.nMaxFile = bufferLimit; 325 ofn.lpstrTitle = titleBuffer; 326 ofn.lpstrInitialDir = directoryBuffer; 327 ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | 328 OFN_ENABLEHOOK | OFN_EXPLORER | OFN_ENABLESIZING; 329 fileFilter = env->GetObjectField(peer, 330 AwtFileDialog::fileFilterID); 331 if (!JNU_IsNull(env,fileFilter)) { 332 ofn.Flags |= OFN_ENABLEINCLUDENOTIFY; 333 } 334 ofn.lCustData = (LPARAM)peer; 335 ofn.lpfnHook = (LPOFNHOOKPROC)FileDialogHookProc; 336 337 if (multipleMode == JNI_TRUE) { 338 ofn.Flags |= OFN_ALLOWMULTISELECT; 339 } 340 341 // Save current directory, so we can reset if it changes. 342 currentDirectory = new TCHAR[MAX_PATH+1]; 343 344 VERIFY(::GetCurrentDirectory(MAX_PATH, currentDirectory) > 0); 345 346 mode = env->GetIntField(target, AwtFileDialog::modeID); 347 348 AwtDialog::CheckInstallModalHook(); 349 350 // show the Win32 file dialog 351 if (mode == java_awt_FileDialog_LOAD) { 352 result = AwtFileDialog::GetOpenFileName(&ofn); 353 } else { 354 result = AwtFileDialog::GetSaveFileName(&ofn); 355 } 356 // Fix for 4181310: FileDialog does not show up. 357 // If the dialog is not shown because of invalid file name 358 // replace the file name by empty string. 359 if (!result) { 360 dlgerr = ::CommDlgExtendedError(); 361 if (dlgerr == FNERR_INVALIDFILENAME) { 362 _tcscpy_s(fileBuffer, bufferLimit, TEXT("")); 363 if (mode == java_awt_FileDialog_LOAD) { 364 result = AwtFileDialog::GetOpenFileName(&ofn); 365 } else { 366 result = AwtFileDialog::GetSaveFileName(&ofn); 367 } 368 } 369 } 370 371 AwtDialog::CheckUninstallModalHook(); 372 373 DASSERT(env->GetLongField(peer, AwtComponent::hwndID) == 0L); 374 375 AwtDialog::ModalActivateNextWindow(NULL, target, peer); 376 377 VERIFY(::SetCurrentDirectory(currentDirectory)); 378 379 // Report result to peer. 380 if (result) { 381 jint length = multipleMode 382 ? (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile) 383 : (jint)_tcslen(ofn.lpstrFile); 384 jcharArray jnames = env->NewCharArray(length); 385 if (jnames == NULL) { 386 throw std::bad_alloc(); 387 } 388 env->SetCharArrayRegion(jnames, 0, length, (jchar*)ofn.lpstrFile); 389 390 env->CallVoidMethod(peer, AwtFileDialog::handleSelectedMID, jnames); 391 env->DeleteLocalRef(jnames); 392 } else { 393 env->CallVoidMethod(peer, AwtFileDialog::handleCancelMID); 394 } 395 DASSERT(!safe_ExceptionOccurred(env)); 396 } catch (...) { 397 398 env->DeleteLocalRef(target); 399 env->DeleteLocalRef(parent); 400 env->DeleteLocalRef(title); 401 env->DeleteLocalRef(directory); 402 env->DeleteLocalRef(file); 403 env->DeleteLocalRef(fileFilter); 404 env->DeleteGlobalRef(peer); 405 406 delete[] currentDirectory; 407 if (ofn.lpstrFile) 408 delete[] ofn.lpstrFile; 409 throw; 410 } 411 412 env->DeleteLocalRef(target); 413 env->DeleteLocalRef(parent); 414 env->DeleteLocalRef(title); 415 env->DeleteLocalRef(directory); 416 env->DeleteLocalRef(file); 417 env->DeleteLocalRef(fileFilter); 418 env->DeleteGlobalRef(peer); 419 420 delete[] currentDirectory; 421 if (ofn.lpstrFile) 422 delete[] ofn.lpstrFile; 423 } 424 425 BOOL 426 AwtFileDialog::GetOpenFileName(LPOPENFILENAME data) { 427 return static_cast<BOOL>(reinterpret_cast<INT_PTR>( 428 AwtToolkit::GetInstance().InvokeFunction((void*(*)(void*)) 429 ::GetOpenFileName, data))); 430 431 } 432 433 BOOL 434 AwtFileDialog::GetSaveFileName(LPOPENFILENAME data) { 435 return static_cast<BOOL>(reinterpret_cast<INT_PTR>( 436 AwtToolkit::GetInstance().InvokeFunction((void *(*)(void *)) 437 ::GetSaveFileName, data))); 438 439 } 440 441 BOOL AwtFileDialog::InheritsNativeMouseWheelBehavior() {return true;} 442 443 void AwtFileDialog::_DisposeOrHide(void *param) 444 { 445 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 446 447 jobject self = (jobject)param; 448 449 HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID)); 450 if (::IsWindow(hdlg)) 451 { 452 ::SendMessage(hdlg, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), 453 (LPARAM)hdlg); 454 } 455 456 env->DeleteGlobalRef(self); 457 } 458 459 void AwtFileDialog::_ToFront(void *param) 460 { 461 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 462 463 jobject self = (jobject)param; 464 HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID)); 465 if (::IsWindow(hdlg)) 466 { 467 ::SetWindowPos(hdlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 468 } 469 470 env->DeleteGlobalRef(self); 471 } 472 473 void AwtFileDialog::_ToBack(void *param) 474 { 475 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 476 477 jobject self = (jobject)param; 478 HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID)); 479 if (::IsWindow(hdlg)) 480 { 481 ::SetWindowPos(hdlg, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 482 } 483 484 env->DeleteGlobalRef(self); 485 } 486 487 // Returns the length of the double null terminated output buffer 488 UINT AwtFileDialog::GetBufferLength(LPTSTR buffer, UINT limit) 489 { 490 UINT index = 0; 491 while ((index < limit) && 492 (buffer[index] != NULL || buffer[index+1] != NULL)) 493 { 494 index++; 495 } 496 return index; 497 } 498 499 /************************************************************************ 500 * WFileDialogPeer native methods 501 */ 502 503 extern "C" { 504 505 JNIEXPORT void JNICALL 506 Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls) 507 { 508 TRY; 509 510 AwtFileDialog::parentID = 511 env->GetFieldID(cls, "parent", "Lsun/awt/windows/WComponentPeer;"); 512 DASSERT(AwtFileDialog::parentID != NULL); 513 CHECK_NULL(AwtFileDialog::parentID); 514 515 AwtFileDialog::fileFilterID = 516 env->GetFieldID(cls, "fileFilter", "Ljava/io/FilenameFilter;"); 517 DASSERT(AwtFileDialog::fileFilterID != NULL); 518 CHECK_NULL(AwtFileDialog::fileFilterID); 519 520 AwtFileDialog::setHWndMID = env->GetMethodID(cls, "setHWnd", "(J)V"); 521 DASSERT(AwtFileDialog::setHWndMID != NULL); 522 CHECK_NULL(AwtFileDialog::setHWndMID); 523 524 AwtFileDialog::handleSelectedMID = 525 env->GetMethodID(cls, "handleSelected", "([C)V"); 526 DASSERT(AwtFileDialog::handleSelectedMID != NULL); 527 CHECK_NULL(AwtFileDialog::handleSelectedMID); 528 529 AwtFileDialog::handleCancelMID = 530 env->GetMethodID(cls, "handleCancel", "()V"); 531 DASSERT(AwtFileDialog::handleCancelMID != NULL); 532 CHECK_NULL(AwtFileDialog::handleCancelMID); 533 534 AwtFileDialog::checkFilenameFilterMID = 535 env->GetMethodID(cls, "checkFilenameFilter", "(Ljava/lang/String;)Z"); 536 DASSERT(AwtFileDialog::checkFilenameFilterMID != NULL); 537 CHECK_NULL(AwtFileDialog::checkFilenameFilterMID); 538 539 AwtFileDialog::isMultipleModeMID = env->GetMethodID(cls, "isMultipleMode", "()Z"); 540 DASSERT(AwtFileDialog::isMultipleModeMID != NULL); 541 CHECK_NULL(AwtFileDialog::isMultipleModeMID); 542 543 /* java.awt.FileDialog fields */ 544 cls = env->FindClass("java/awt/FileDialog"); 545 CHECK_NULL(cls); 546 547 AwtFileDialog::modeID = env->GetFieldID(cls, "mode", "I"); 548 DASSERT(AwtFileDialog::modeID != NULL); 549 CHECK_NULL(AwtFileDialog::modeID); 550 551 AwtFileDialog::dirID = env->GetFieldID(cls, "dir", "Ljava/lang/String;"); 552 DASSERT(AwtFileDialog::dirID != NULL); 553 CHECK_NULL(AwtFileDialog::dirID); 554 555 AwtFileDialog::fileID = env->GetFieldID(cls, "file", "Ljava/lang/String;"); 556 DASSERT(AwtFileDialog::fileID != NULL); 557 CHECK_NULL(AwtFileDialog::fileID); 558 559 AwtFileDialog::filterID = 560 env->GetFieldID(cls, "filter", "Ljava/io/FilenameFilter;"); 561 DASSERT(AwtFileDialog::filterID != NULL); 562 563 CATCH_BAD_ALLOC; 564 } 565 566 JNIEXPORT void JNICALL 567 Java_sun_awt_windows_WFileDialogPeer_setFilterString(JNIEnv *env, jclass cls, 568 jstring filterDescription) 569 { 570 TRY; 571 572 AwtFileDialog::Initialize(env, filterDescription); 573 574 CATCH_BAD_ALLOC; 575 } 576 577 JNIEXPORT void JNICALL 578 Java_sun_awt_windows_WFileDialogPeer__1show(JNIEnv *env, jobject peer) 579 { 580 TRY; 581 582 /* 583 * Fix for 4906972. 584 * 'peer' reference has to be global as it's used further in another thread. 585 */ 586 jobject peerGlobal = env->NewGlobalRef(peer); 587 588 AwtToolkit::GetInstance().InvokeFunction(AwtFileDialog::Show, peerGlobal); 589 590 env->DeleteGlobalRef(peerGlobal); 591 592 CATCH_BAD_ALLOC; 593 } 594 595 JNIEXPORT void JNICALL 596 Java_sun_awt_windows_WFileDialogPeer__1dispose(JNIEnv *env, jobject peer) 597 { 598 TRY_NO_VERIFY; 599 600 jobject peerGlobal = env->NewGlobalRef(peer); 601 602 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_DisposeOrHide, 603 (void *)peerGlobal); 604 // peerGlobal ref is deleted in _DisposeOrHide 605 606 CATCH_BAD_ALLOC; 607 } 608 609 JNIEXPORT void JNICALL 610 Java_sun_awt_windows_WFileDialogPeer__1hide(JNIEnv *env, jobject peer) 611 { 612 TRY; 613 614 jobject peerGlobal = env->NewGlobalRef(peer); 615 616 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_DisposeOrHide, 617 (void *)peerGlobal); 618 // peerGlobal ref is deleted in _DisposeOrHide 619 620 CATCH_BAD_ALLOC; 621 } 622 623 JNIEXPORT void JNICALL 624 Java_sun_awt_windows_WFileDialogPeer_toFront(JNIEnv *env, jobject peer) 625 { 626 TRY; 627 628 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_ToFront, 629 (void *)(env->NewGlobalRef(peer))); 630 // global ref is deleted in _ToFront 631 632 CATCH_BAD_ALLOC; 633 } 634 635 JNIEXPORT void JNICALL 636 Java_sun_awt_windows_WFileDialogPeer_toBack(JNIEnv *env, jobject peer) 637 { 638 TRY; 639 640 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_ToBack, 641 (void *)(env->NewGlobalRef(peer))); 642 // global ref is deleted in _ToBack 643 644 CATCH_BAD_ALLOC; 645 } 646 647 } /* extern "C" */ --- EOF ---