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 = multipleMode
 376                     ? (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile)
 377                     : (jint)_tcslen(ofn.lpstrFile);
 378             jcharArray jnames = env->NewCharArray(length);
 379             env->SetCharArrayRegion(jnames, 0, length, (jchar*)ofn.lpstrFile);
 380 
 381             env->CallVoidMethod(peer, AwtFileDialog::handleSelectedMID, jnames);
 382             env->DeleteLocalRef(jnames);
 383         } else {
 384             env->CallVoidMethod(peer, AwtFileDialog::handleCancelMID);
 385         }
 386         DASSERT(!safe_ExceptionOccurred(env));
 387     } catch (...) {
 388 
 389         env->DeleteLocalRef(target);
 390         env->DeleteLocalRef(parent);
 391         env->DeleteLocalRef(title);
 392         env->DeleteLocalRef(directory);
 393         env->DeleteLocalRef(file);
 394         env->DeleteLocalRef(fileFilter);
 395         env->DeleteGlobalRef(peer);
 396 
 397         delete[] currentDirectory;
 398         if (ofn.lpstrFile)
 399             delete[] ofn.lpstrFile;
 400         throw;
 401     }
 402 
 403     env->DeleteLocalRef(target);
 404     env->DeleteLocalRef(parent);
 405     env->DeleteLocalRef(title);
 406     env->DeleteLocalRef(directory);
 407     env->DeleteLocalRef(file);
 408     env->DeleteLocalRef(fileFilter);
 409     env->DeleteGlobalRef(peer);
 410 
 411     delete[] currentDirectory;
 412     if (ofn.lpstrFile)
 413         delete[] ofn.lpstrFile;
 414 }
 415 
 416 BOOL
 417 AwtFileDialog::GetOpenFileName(LPOPENFILENAME data) {
 418     return static_cast<BOOL>(reinterpret_cast<INT_PTR>(
 419         AwtToolkit::GetInstance().InvokeFunction((void*(*)(void*))
 420                      ::GetOpenFileName, data)));
 421 
 422 }
 423 
 424 BOOL
 425 AwtFileDialog::GetSaveFileName(LPOPENFILENAME data) {
 426     return static_cast<BOOL>(reinterpret_cast<INT_PTR>(
 427         AwtToolkit::GetInstance().InvokeFunction((void *(*)(void *))
 428                      ::GetSaveFileName, data)));
 429 
 430 }
 431 
 432 BOOL AwtFileDialog::InheritsNativeMouseWheelBehavior() {return true;}
 433 
 434 void AwtFileDialog::_DisposeOrHide(void *param)
 435 {
 436     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 437 
 438     jobject self = (jobject)param;
 439 
 440     HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID));
 441     if (::IsWindow(hdlg))
 442     {
 443         ::SendMessage(hdlg, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0),
 444                       (LPARAM)hdlg);
 445     }
 446 
 447     env->DeleteGlobalRef(self);
 448 }
 449 
 450 void AwtFileDialog::_ToFront(void *param)
 451 {
 452     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 453 
 454     jobject self = (jobject)param;
 455     HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID));
 456     if (::IsWindow(hdlg))
 457     {
 458         ::SetWindowPos(hdlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
 459     }
 460 
 461     env->DeleteGlobalRef(self);
 462 }
 463 
 464 void AwtFileDialog::_ToBack(void *param)
 465 {
 466     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 467 
 468     jobject self = (jobject)param;
 469     HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID));
 470     if (::IsWindow(hdlg))
 471     {
 472         ::SetWindowPos(hdlg, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 473     }
 474 
 475     env->DeleteGlobalRef(self);
 476 }
 477 
 478 // Returns the length of the double null terminated output buffer
 479 UINT AwtFileDialog::GetBufferLength(LPTSTR buffer, UINT limit)
 480 {
 481     UINT index = 0;
 482     while ((index < limit) &&
 483            (buffer[index] != NULL || buffer[index+1] != NULL))
 484     {
 485         index++;
 486     }
 487     return index;
 488 }
 489 
 490 /************************************************************************
 491  * WFileDialogPeer native methods
 492  */
 493 
 494 extern "C" {
 495 
 496 JNIEXPORT void JNICALL
 497 Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls)
 498 {
 499     TRY;
 500 
 501     AwtFileDialog::parentID =
 502         env->GetFieldID(cls, "parent", "Lsun/awt/windows/WComponentPeer;");
 503     AwtFileDialog::fileFilterID =
 504         env->GetFieldID(cls, "fileFilter", "Ljava/io/FilenameFilter;");
 505     AwtFileDialog::setHWndMID =
 506         env->GetMethodID(cls, "setHWnd", "(J)V");
 507     AwtFileDialog::handleSelectedMID =
 508         env->GetMethodID(cls, "handleSelected", "([C)V");
 509     AwtFileDialog::handleCancelMID =
 510         env->GetMethodID(cls, "handleCancel", "()V");
 511     AwtFileDialog::checkFilenameFilterMID =
 512         env->GetMethodID(cls, "checkFilenameFilter", "(Ljava/lang/String;)Z");
 513     AwtFileDialog::isMultipleModeMID = env->GetMethodID(cls, "isMultipleMode", "()Z");
 514 
 515     /* java.awt.FileDialog fields */
 516     cls = env->FindClass("java/awt/FileDialog");
 517     if (cls == NULL) {
 518         return;
 519     }
 520     AwtFileDialog::modeID = env->GetFieldID(cls, "mode", "I");
 521     AwtFileDialog::dirID = env->GetFieldID(cls, "dir", "Ljava/lang/String;");
 522     AwtFileDialog::fileID = env->GetFieldID(cls, "file", "Ljava/lang/String;");
 523     AwtFileDialog::filterID =
 524         env->GetFieldID(cls, "filter", "Ljava/io/FilenameFilter;");
 525 
 526     DASSERT(AwtFileDialog::parentID != NULL);
 527     DASSERT(AwtFileDialog::setHWndMID != NULL);
 528     DASSERT(AwtFileDialog::handleSelectedMID != NULL);
 529     DASSERT(AwtFileDialog::handleCancelMID != NULL);
 530     DASSERT(AwtFileDialog::isMultipleModeMID != NULL);
 531 
 532     DASSERT(AwtFileDialog::modeID != NULL);
 533     DASSERT(AwtFileDialog::dirID != NULL);
 534     DASSERT(AwtFileDialog::fileID != NULL);
 535     DASSERT(AwtFileDialog::filterID != NULL);
 536 
 537     CATCH_BAD_ALLOC;
 538 }
 539 
 540 JNIEXPORT void JNICALL
 541 Java_sun_awt_windows_WFileDialogPeer_setFilterString(JNIEnv *env, jclass cls,
 542                                                      jstring filterDescription)
 543 {
 544     TRY;
 545 
 546     AwtFileDialog::Initialize(env, filterDescription);
 547 
 548     CATCH_BAD_ALLOC;
 549 }
 550 
 551 JNIEXPORT void JNICALL
 552 Java_sun_awt_windows_WFileDialogPeer__1show(JNIEnv *env, jobject peer)
 553 {
 554     TRY;
 555 
 556     /*
 557      * Fix for 4906972.
 558      * 'peer' reference has to be global as it's used further in another thread.
 559      */
 560     jobject peerGlobal = env->NewGlobalRef(peer);
 561 
 562     AwtToolkit::GetInstance().InvokeFunction(AwtFileDialog::Show, peerGlobal);
 563 
 564     env->DeleteGlobalRef(peerGlobal);
 565 
 566     CATCH_BAD_ALLOC;
 567 }
 568 
 569 JNIEXPORT void JNICALL
 570 Java_sun_awt_windows_WFileDialogPeer__1dispose(JNIEnv *env, jobject peer)
 571 {
 572     TRY_NO_VERIFY;
 573 
 574     jobject peerGlobal = env->NewGlobalRef(peer);
 575 
 576     AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_DisposeOrHide,
 577         (void *)peerGlobal);
 578     // peerGlobal ref is deleted in _DisposeOrHide
 579 
 580     CATCH_BAD_ALLOC;
 581 }
 582 
 583 JNIEXPORT void JNICALL
 584 Java_sun_awt_windows_WFileDialogPeer__1hide(JNIEnv *env, jobject peer)
 585 {
 586     TRY;
 587 
 588     jobject peerGlobal = env->NewGlobalRef(peer);
 589 
 590     AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_DisposeOrHide,
 591         (void *)peerGlobal);
 592     // peerGlobal ref is deleted in _DisposeOrHide
 593 
 594     CATCH_BAD_ALLOC;
 595 }
 596 
 597 JNIEXPORT void JNICALL
 598 Java_sun_awt_windows_WFileDialogPeer_toFront(JNIEnv *env, jobject peer)
 599 {
 600     TRY;
 601 
 602     AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_ToFront,
 603                                        (void *)(env->NewGlobalRef(peer)));
 604     // global ref is deleted in _ToFront
 605 
 606     CATCH_BAD_ALLOC;
 607 }
 608 
 609 JNIEXPORT void JNICALL
 610 Java_sun_awt_windows_WFileDialogPeer_toBack(JNIEnv *env, jobject peer)
 611 {
 612     TRY;
 613 
 614     AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_ToBack,
 615                                        (void *)(env->NewGlobalRef(peer)));
 616     // global ref is deleted in _ToBack
 617 
 618     CATCH_BAD_ALLOC;
 619 }
 620 
 621 } /* extern "C" */