1 /* 2 * Copyright (c) 1996, 2010, 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_fileFilterString, 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 // Call FilenameFilter.accept with path and filename 184 UINT uRes = (env->CallBooleanMethod(peer, 185 AwtFileDialog::checkFilenameFilterMID, strPath) == JNI_TRUE); 186 env->DeleteLocalRef(strPath); 187 return uRes; 188 } else if (notifyEx->hdr.code == CDN_FILEOK) { 189 // This notification is sent when user selects some file and presses 190 // OK button; it is not sent when no file is selected. So it's time 191 // to unblock all the windows blocked by this dialog as it will 192 // be closed soon 193 env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong)0); 194 } else if (notifyEx->hdr.code == CDN_SELCHANGE) { 195 // reallocate the buffer if the buffer is too small 196 LPOPENFILENAME lpofn = (LPOPENFILENAME)GetProp(parent, OpenFileNameProp); 197 198 UINT nLength = CommDlg_OpenSave_GetSpec(parent, NULL, 0) + 199 CommDlg_OpenSave_GetFolderPath(parent, NULL, 0); 200 201 if (lpofn->nMaxFile < nLength) 202 { 203 // allocate new buffer 204 LPTSTR newBuffer = new TCHAR[nLength]; 205 206 if (newBuffer) { 207 memset(newBuffer, 0, nLength * sizeof(TCHAR)); 208 LPTSTR oldBuffer = lpofn->lpstrFile; 209 lpofn->lpstrFile = newBuffer; 210 lpofn->nMaxFile = nLength; 211 // free the previously allocated buffer 212 if (oldBuffer) { 213 delete[] oldBuffer; 214 } 215 216 } 217 } 218 } 219 } 220 break; 221 } 222 } 223 224 return FALSE; 225 226 CATCH_BAD_ALLOC_RET(TRUE); 227 } 228 229 void 230 AwtFileDialog::Show(void *p) 231 { 232 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 233 jobject peer; 234 LPTSTR fileBuffer = NULL; 235 LPTSTR currentDirectory = NULL; 236 jint mode = 0; 237 BOOL result = FALSE; 238 DWORD dlgerr; 239 jstring directory = NULL; 240 jstring title = NULL; 241 jstring file = NULL; 242 jobject fileFilter = NULL; 243 jobject target = NULL; 244 jobject parent = NULL; 245 AwtComponent* awtParent = NULL; 246 jboolean multipleMode = JNI_FALSE; 247 248 OPENFILENAME ofn; 249 memset(&ofn, 0, sizeof(ofn)); 250 251 /* 252 * There's a situation (see bug 4906972) when InvokeFunction (by which this method is called) 253 * returnes earlier than this method returnes. Probably it's caused due to ReplyMessage system call. 254 * So for the avoidance of this mistiming we need to make new global reference here 255 * (not local as it's used by the hook) and then manage it independently of the calling thread. 256 */ 257 peer = env->NewGlobalRef((jobject)p); 258 259 try { 260 DASSERT(peer); 261 target = env->GetObjectField(peer, AwtObject::targetID); 262 parent = env->GetObjectField(peer, AwtFileDialog::parentID); 263 if (parent != NULL) { 264 awtParent = (AwtComponent *)JNI_GET_PDATA(parent); 265 } 266 // DASSERT(awtParent); 267 title = (jstring)(env)->GetObjectField(target, AwtDialog::titleID); 268 HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL; 269 270 if (title == NULL || env->GetStringLength(title)==0) { 271 title = JNU_NewStringPlatform(env, L" "); 272 } 273 274 JavaStringBuffer titleBuffer(env, title); 275 directory = 276 (jstring)env->GetObjectField(target, AwtFileDialog::dirID); 277 JavaStringBuffer directoryBuffer(env, directory); 278 279 multipleMode = env->CallBooleanMethod(peer, AwtFileDialog::isMultipleModeMID); 280 281 UINT bufferLimit; 282 if (multipleMode == JNI_TRUE) { 283 bufferLimit = MULTIPLE_MODE_BUFFER_LIMIT; 284 } else { 285 bufferLimit = SINGLE_MODE_BUFFER_LIMIT; 286 } 287 LPTSTR fileBuffer = new TCHAR[bufferLimit]; 288 memset(fileBuffer, 0, bufferLimit * sizeof(TCHAR)); 289 290 file = (jstring)env->GetObjectField(target, AwtFileDialog::fileID); 291 if (file != NULL) { 292 LPCTSTR tmp = JNU_GetStringPlatformChars(env, file, NULL); 293 _tcsncpy(fileBuffer, tmp, bufferLimit - 2); // the fileBuffer is double null terminated string 294 JNU_ReleaseStringPlatformChars(env, file, tmp); 295 } else { 296 fileBuffer[0] = _T('\0'); 297 } 298 299 ofn.lStructSize = sizeof(ofn); 300 ofn.lpstrFilter = s_fileFilterString; 301 ofn.nFilterIndex = 1; 302 /* 303 Fix for 6488834. 304 To disable Win32 native parent modality we have to set 305 hwndOwner field to either NULL or some hidden window. For 306 parentless dialogs we use NULL to show them in the taskbar, 307 and for all other dialogs AwtToolkit's HWND is used. 308 */ 309 if (awtParent != NULL) 310 { 311 ofn.hwndOwner = AwtToolkit::GetInstance().GetHWnd(); 312 } 313 else 314 { 315 ofn.hwndOwner = NULL; 316 } 317 ofn.lpstrFile = fileBuffer; 318 ofn.nMaxFile = bufferLimit; 319 ofn.lpstrTitle = titleBuffer; 320 ofn.lpstrInitialDir = directoryBuffer; 321 ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | 322 OFN_ENABLEHOOK | OFN_EXPLORER | OFN_ENABLESIZING; 323 fileFilter = env->GetObjectField(peer, 324 AwtFileDialog::fileFilterID); 325 if (!JNU_IsNull(env,fileFilter)) { 326 ofn.Flags |= OFN_ENABLEINCLUDENOTIFY; 327 } 328 ofn.lCustData = (LPARAM)peer; 329 ofn.lpfnHook = (LPOFNHOOKPROC)FileDialogHookProc; 330 331 if (multipleMode == JNI_TRUE) { 332 ofn.Flags |= OFN_ALLOWMULTISELECT; 333 } 334 335 // Save current directory, so we can reset if it changes. 336 currentDirectory = new TCHAR[MAX_PATH+1]; 337 338 VERIFY(::GetCurrentDirectory(MAX_PATH, currentDirectory) > 0); 339 340 mode = env->GetIntField(target, AwtFileDialog::modeID); 341 342 AwtDialog::CheckInstallModalHook(); 343 344 // show the Win32 file dialog 345 if (mode == java_awt_FileDialog_LOAD) { 346 result = AwtFileDialog::GetOpenFileName(&ofn); 347 } else { 348 result = AwtFileDialog::GetSaveFileName(&ofn); 349 } 350 // Fix for 4181310: FileDialog does not show up. 351 // If the dialog is not shown because of invalid file name 352 // replace the file name by empty string. 353 if (!result) { 354 dlgerr = ::CommDlgExtendedError(); 355 if (dlgerr == FNERR_INVALIDFILENAME) { 356 _tcscpy(fileBuffer, TEXT("")); 357 if (mode == java_awt_FileDialog_LOAD) { 358 result = AwtFileDialog::GetOpenFileName(&ofn); 359 } else { 360 result = AwtFileDialog::GetSaveFileName(&ofn); 361 } 362 } 363 } 364 365 AwtDialog::CheckUninstallModalHook(); 366 367 DASSERT(env->GetLongField(peer, AwtComponent::hwndID) == 0L); 368 369 AwtDialog::ModalActivateNextWindow(NULL, target, peer); 370 371 VERIFY(::SetCurrentDirectory(currentDirectory)); 372 373 // Report result to peer. 374 if (result) { 375 jint length = (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile); 376 jcharArray jnames = env->NewCharArray(length); 377 env->SetCharArrayRegion(jnames, 0, length, (jchar*)ofn.lpstrFile); 378 379 env->CallVoidMethod(peer, AwtFileDialog::handleSelectedMID, jnames); 380 env->DeleteLocalRef(jnames); 381 } else { 382 env->CallVoidMethod(peer, AwtFileDialog::handleCancelMID); 383 } 384 DASSERT(!safe_ExceptionOccurred(env)); 385 } catch (...) { 386 387 env->DeleteLocalRef(target); 388 env->DeleteLocalRef(parent); 389 env->DeleteLocalRef(title); 390 env->DeleteLocalRef(directory); 391 env->DeleteLocalRef(file); 392 env->DeleteLocalRef(fileFilter); 393 env->DeleteGlobalRef(peer); 394 395 delete[] currentDirectory; 396 if (ofn.lpstrFile) 397 delete[] ofn.lpstrFile; 398 throw; 399 } 400 401 env->DeleteLocalRef(target); 402 env->DeleteLocalRef(parent); 403 env->DeleteLocalRef(title); 404 env->DeleteLocalRef(directory); 405 env->DeleteLocalRef(file); 406 env->DeleteLocalRef(fileFilter); 407 env->DeleteGlobalRef(peer); 408 409 delete[] currentDirectory; 410 if (ofn.lpstrFile) 411 delete[] ofn.lpstrFile; 412 } 413 414 BOOL 415 AwtFileDialog::GetOpenFileName(LPOPENFILENAME data) { 416 return static_cast<BOOL>(reinterpret_cast<INT_PTR>( 417 AwtToolkit::GetInstance().InvokeFunction((void*(*)(void*)) 418 ::GetOpenFileName, data))); 419 420 } 421 422 BOOL 423 AwtFileDialog::GetSaveFileName(LPOPENFILENAME data) { 424 return static_cast<BOOL>(reinterpret_cast<INT_PTR>( 425 AwtToolkit::GetInstance().InvokeFunction((void *(*)(void *)) 426 ::GetSaveFileName, data))); 427 428 } 429 430 BOOL AwtFileDialog::InheritsNativeMouseWheelBehavior() {return true;} 431 432 void AwtFileDialog::_DisposeOrHide(void *param) 433 { 434 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 435 436 jobject self = (jobject)param; 437 438 HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID)); 439 if (::IsWindow(hdlg)) 440 { 441 ::SendMessage(hdlg, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), 442 (LPARAM)hdlg); 443 } 444 445 env->DeleteGlobalRef(self); 446 } 447 448 void AwtFileDialog::_ToFront(void *param) 449 { 450 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 451 452 jobject self = (jobject)param; 453 HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID)); 454 if (::IsWindow(hdlg)) 455 { 456 ::SetWindowPos(hdlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 457 } 458 459 env->DeleteGlobalRef(self); 460 } 461 462 void AwtFileDialog::_ToBack(void *param) 463 { 464 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 465 466 jobject self = (jobject)param; 467 HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID)); 468 if (::IsWindow(hdlg)) 469 { 470 ::SetWindowPos(hdlg, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 471 } 472 473 env->DeleteGlobalRef(self); 474 } 475 476 // Returns the length of the double null terminated output buffer 477 UINT AwtFileDialog::GetBufferLength(LPTSTR buffer, UINT limit) 478 { 479 UINT index = 0; 480 while ((index < limit) && 481 (buffer[index] != NULL || buffer[index+1] != NULL)) 482 { 483 index++; 484 } 485 return index; 486 } 487 488 /************************************************************************ 489 * WFileDialogPeer native methods 490 */ 491 492 extern "C" { 493 494 JNIEXPORT void JNICALL 495 Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls) 496 { 497 TRY; 498 499 AwtFileDialog::parentID = 500 env->GetFieldID(cls, "parent", "Lsun/awt/windows/WComponentPeer;"); 501 AwtFileDialog::fileFilterID = 502 env->GetFieldID(cls, "fileFilter", "Ljava/io/FilenameFilter;"); 503 AwtFileDialog::setHWndMID = 504 env->GetMethodID(cls, "setHWnd", "(J)V"); 505 AwtFileDialog::handleSelectedMID = 506 env->GetMethodID(cls, "handleSelected", "([C)V"); 507 AwtFileDialog::handleCancelMID = 508 env->GetMethodID(cls, "handleCancel", "()V"); 509 AwtFileDialog::checkFilenameFilterMID = 510 env->GetMethodID(cls, "checkFilenameFilter", "(Ljava/lang/String;)Z"); 511 AwtFileDialog::isMultipleModeMID = env->GetMethodID(cls, "isMultipleMode", "()Z"); 512 513 /* java.awt.FileDialog fields */ 514 cls = env->FindClass("java/awt/FileDialog"); 515 if (cls == NULL) { 516 return; 517 } 518 AwtFileDialog::modeID = env->GetFieldID(cls, "mode", "I"); 519 AwtFileDialog::dirID = env->GetFieldID(cls, "dir", "Ljava/lang/String;"); 520 AwtFileDialog::fileID = env->GetFieldID(cls, "file", "Ljava/lang/String;"); 521 AwtFileDialog::filterID = 522 env->GetFieldID(cls, "filter", "Ljava/io/FilenameFilter;"); 523 524 DASSERT(AwtFileDialog::parentID != NULL); 525 DASSERT(AwtFileDialog::setHWndMID != NULL); 526 DASSERT(AwtFileDialog::handleSelectedMID != NULL); 527 DASSERT(AwtFileDialog::handleCancelMID != NULL); 528 DASSERT(AwtFileDialog::isMultipleModeMID != NULL); 529 530 DASSERT(AwtFileDialog::modeID != NULL); 531 DASSERT(AwtFileDialog::dirID != NULL); 532 DASSERT(AwtFileDialog::fileID != NULL); 533 DASSERT(AwtFileDialog::filterID != NULL); 534 535 CATCH_BAD_ALLOC; 536 } 537 538 JNIEXPORT void JNICALL 539 Java_sun_awt_windows_WFileDialogPeer_setFilterString(JNIEnv *env, jclass cls, 540 jstring filterDescription) 541 { 542 TRY; 543 544 AwtFileDialog::Initialize(env, filterDescription); 545 546 CATCH_BAD_ALLOC; 547 } 548 549 JNIEXPORT void JNICALL 550 Java_sun_awt_windows_WFileDialogPeer__1show(JNIEnv *env, jobject peer) 551 { 552 TRY; 553 554 /* 555 * Fix for 4906972. 556 * 'peer' reference has to be global as it's used further in another thread. 557 */ 558 jobject peerGlobal = env->NewGlobalRef(peer); 559 560 AwtToolkit::GetInstance().InvokeFunction(AwtFileDialog::Show, peerGlobal); 561 562 env->DeleteGlobalRef(peerGlobal); 563 564 CATCH_BAD_ALLOC; 565 } 566 567 JNIEXPORT void JNICALL 568 Java_sun_awt_windows_WFileDialogPeer__1dispose(JNIEnv *env, jobject peer) 569 { 570 TRY_NO_VERIFY; 571 572 jobject peerGlobal = env->NewGlobalRef(peer); 573 574 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_DisposeOrHide, 575 (void *)peerGlobal); 576 // peerGlobal ref is deleted in _DisposeOrHide 577 578 CATCH_BAD_ALLOC; 579 } 580 581 JNIEXPORT void JNICALL 582 Java_sun_awt_windows_WFileDialogPeer__1hide(JNIEnv *env, jobject peer) 583 { 584 TRY; 585 586 jobject peerGlobal = env->NewGlobalRef(peer); 587 588 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_DisposeOrHide, 589 (void *)peerGlobal); 590 // peerGlobal ref is deleted in _DisposeOrHide 591 592 CATCH_BAD_ALLOC; 593 } 594 595 JNIEXPORT void JNICALL 596 Java_sun_awt_windows_WFileDialogPeer_toFront(JNIEnv *env, jobject peer) 597 { 598 TRY; 599 600 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_ToFront, 601 (void *)(env->NewGlobalRef(peer))); 602 // global ref is deleted in _ToFront 603 604 CATCH_BAD_ALLOC; 605 } 606 607 JNIEXPORT void JNICALL 608 Java_sun_awt_windows_WFileDialogPeer_toBack(JNIEnv *env, jobject peer) 609 { 610 TRY; 611 612 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_ToBack, 613 (void *)(env->NewGlobalRef(peer))); 614 // global ref is deleted in _ToBack 615 616 CATCH_BAD_ALLOC; 617 } 618 619 } /* extern "C" */