1 /* 2 * Copyright (c) 1996, 2016, 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 case WM_SETICON: { 111 return 0; 112 } 113 } 114 115 WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp)); 116 return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam); 117 } 118 119 static UINT_PTR CALLBACK 120 FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) 121 { 122 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 123 124 TRY; 125 126 HWND parent = ::GetParent(hdlg); 127 128 switch(uiMsg) { 129 case WM_INITDIALOG: { 130 OPENFILENAME *ofn = (OPENFILENAME *)lParam; 131 jobject peer = (jobject)(ofn->lCustData); 132 env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, 133 (jlong)parent); 134 ::SetProp(parent, ModalDialogPeerProp, reinterpret_cast<HANDLE>(peer)); 135 136 // fix for 4508670 - disable CS_SAVEBITS 137 DWORD style = ::GetClassLong(hdlg,GCL_STYLE); 138 ::SetClassLong(hdlg,GCL_STYLE,style & ~CS_SAVEBITS); 139 140 // set appropriate icon for parentless dialogs 141 jobject awtParent = env->GetObjectField(peer, AwtFileDialog::parentID); 142 if (awtParent == NULL) { 143 ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_BIG, 144 (LPARAM)AwtToolkit::GetInstance().GetAwtIcon()); 145 } else { 146 AwtWindow *awtWindow = (AwtWindow *)JNI_GET_PDATA(awtParent); 147 ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_BIG, 148 (LPARAM)(awtWindow->GetHIcon())); 149 ::SendMessage(parent, WM_SETICON, (WPARAM)ICON_SMALL, 150 (LPARAM)(awtWindow->GetHIconSm())); 151 env->DeleteLocalRef(awtParent); 152 } 153 154 // subclass dialog's parent to receive additional messages 155 WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(parent, 156 FileDialogWndProc); 157 ::SetProp(parent, NativeDialogWndProcProp, reinterpret_cast<HANDLE>(lpfnWndProc)); 158 159 ::SetProp(parent, OpenFileNameProp, (void *)lParam); 160 161 break; 162 } 163 case WM_DESTROY: { 164 HIMC hIMC = ::ImmGetContext(hdlg); 165 if (hIMC != NULL) { 166 ::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0); 167 ::ImmReleaseContext(hdlg, hIMC); 168 } 169 170 WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(parent, NativeDialogWndProcProp)); 171 ComCtl32Util::GetInstance().UnsubclassHWND(parent, 172 FileDialogWndProc, 173 lpfnWndProc); 174 ::RemoveProp(parent, ModalDialogPeerProp); 175 ::RemoveProp(parent, NativeDialogWndProcProp); 176 ::RemoveProp(parent, OpenFileNameProp); 177 break; 178 } 179 case WM_NOTIFY: { 180 OFNOTIFYEX *notifyEx = (OFNOTIFYEX *)lParam; 181 if (notifyEx) { 182 jobject peer = (jobject)(::GetProp(parent, ModalDialogPeerProp)); 183 if (notifyEx->hdr.code == CDN_INCLUDEITEM) { 184 LPITEMIDLIST pidl = (LPITEMIDLIST)notifyEx->pidl; 185 // Get the filename and directory 186 TCHAR szPath[MAX_PATH]; 187 if (!::SHGetPathFromIDList(pidl, szPath)) { 188 return TRUE; 189 } 190 jstring strPath = JNU_NewStringPlatform(env, szPath); 191 if (strPath == NULL) { 192 throw std::bad_alloc(); 193 } 194 // Call FilenameFilter.accept with path and filename 195 UINT uRes = (env->CallBooleanMethod(peer, 196 AwtFileDialog::checkFilenameFilterMID, strPath) == JNI_TRUE); 197 env->DeleteLocalRef(strPath); 198 return uRes; 199 } else if (notifyEx->hdr.code == CDN_FILEOK) { 200 // This notification is sent when user selects some file and presses 201 // OK button; it is not sent when no file is selected. So it's time 202 // to unblock all the windows blocked by this dialog as it will 203 // be closed soon 204 env->CallVoidMethod(peer, AwtFileDialog::setHWndMID, (jlong)0); 205 } else if (notifyEx->hdr.code == CDN_SELCHANGE) { 206 // reallocate the buffer if the buffer is too small 207 LPOPENFILENAME lpofn = (LPOPENFILENAME)GetProp(parent, OpenFileNameProp); 208 209 UINT nLength = CommDlg_OpenSave_GetSpec(parent, NULL, 0) + 210 CommDlg_OpenSave_GetFolderPath(parent, NULL, 0); 211 212 if (lpofn->nMaxFile < nLength) 213 { 214 // allocate new buffer 215 LPTSTR newBuffer = new TCHAR[nLength]; 216 217 if (newBuffer) { 218 memset(newBuffer, 0, nLength * sizeof(TCHAR)); 219 LPTSTR oldBuffer = lpofn->lpstrFile; 220 lpofn->lpstrFile = newBuffer; 221 lpofn->nMaxFile = nLength; 222 // free the previously allocated buffer 223 if (oldBuffer) { 224 delete[] oldBuffer; 225 } 226 227 } 228 } 229 } 230 } 231 break; 232 } 233 } 234 235 return FALSE; 236 237 CATCH_BAD_ALLOC_RET(TRUE); 238 } 239 240 void 241 AwtFileDialog::Show(void *p) 242 { 243 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 244 jobject peer; 245 LPTSTR fileBuffer = NULL; 246 LPTSTR currentDirectory = NULL; 247 jint mode = 0; 248 BOOL result = FALSE; 249 DWORD dlgerr; 250 jstring directory = NULL; 251 jstring title = NULL; 252 jstring file = NULL; 253 jobject fileFilter = NULL; 254 jobject target = NULL; 255 jobject parent = NULL; 256 AwtComponent* awtParent = NULL; 257 jboolean multipleMode = JNI_FALSE; 258 259 OPENFILENAME ofn; 260 memset(&ofn, 0, sizeof(ofn)); 261 262 peer = (jobject)p; 263 264 try { 265 DASSERT(peer); 266 target = env->GetObjectField(peer, AwtObject::targetID); 267 parent = env->GetObjectField(peer, AwtFileDialog::parentID); 268 if (parent != NULL) { 269 awtParent = (AwtComponent *)JNI_GET_PDATA(parent); 270 } 271 // DASSERT(awtParent); 272 title = (jstring)(env)->GetObjectField(target, AwtDialog::titleID); 273 HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL; 274 275 if (title == NULL || env->GetStringLength(title)==0) { 276 title = JNU_NewStringPlatform(env, L" "); 277 if (title == NULL) { 278 throw std::bad_alloc(); 279 } 280 } 281 282 JavaStringBuffer titleBuffer(env, title); 283 directory = 284 (jstring)env->GetObjectField(target, AwtFileDialog::dirID); 285 JavaStringBuffer directoryBuffer(env, directory); 286 287 multipleMode = env->CallBooleanMethod(peer, AwtFileDialog::isMultipleModeMID); 288 289 UINT bufferLimit; 290 if (multipleMode == JNI_TRUE) { 291 bufferLimit = MULTIPLE_MODE_BUFFER_LIMIT; 292 } else { 293 bufferLimit = SINGLE_MODE_BUFFER_LIMIT; 294 } 295 LPTSTR fileBuffer = new TCHAR[bufferLimit]; 296 memset(fileBuffer, 0, bufferLimit * sizeof(TCHAR)); 297 298 file = (jstring)env->GetObjectField(target, AwtFileDialog::fileID); 299 if (file != NULL) { 300 LPCTSTR tmp = JNU_GetStringPlatformChars(env, file, NULL); 301 _tcsncpy(fileBuffer, tmp, bufferLimit - 2); // the fileBuffer is double null terminated string 302 JNU_ReleaseStringPlatformChars(env, file, tmp); 303 } else { 304 fileBuffer[0] = _T('\0'); 305 } 306 307 ofn.lStructSize = sizeof(ofn); 308 ofn.lpstrFilter = s_fileFilterString; 309 ofn.nFilterIndex = 1; 310 /* 311 Fix for 6488834. 312 To disable Win32 native parent modality we have to set 313 hwndOwner field to either NULL or some hidden window. For 314 parentless dialogs we use NULL to show them in the taskbar, 315 and for all other dialogs AwtToolkit's HWND is used. 316 */ 317 if (awtParent != NULL) 318 { 319 ofn.hwndOwner = AwtToolkit::GetInstance().GetHWnd(); 320 } 321 else 322 { 323 ofn.hwndOwner = NULL; 324 } 325 ofn.lpstrFile = fileBuffer; 326 ofn.nMaxFile = bufferLimit; 327 ofn.lpstrTitle = titleBuffer; 328 ofn.lpstrInitialDir = directoryBuffer; 329 ofn.Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | 330 OFN_ENABLEHOOK | OFN_EXPLORER | OFN_ENABLESIZING; 331 fileFilter = env->GetObjectField(peer, 332 AwtFileDialog::fileFilterID); 333 if (!JNU_IsNull(env,fileFilter)) { 334 ofn.Flags |= OFN_ENABLEINCLUDENOTIFY; 335 } 336 ofn.lCustData = (LPARAM)peer; 337 ofn.lpfnHook = (LPOFNHOOKPROC)FileDialogHookProc; 338 339 if (multipleMode == JNI_TRUE) { 340 ofn.Flags |= OFN_ALLOWMULTISELECT; 341 } 342 343 // Save current directory, so we can reset if it changes. 344 currentDirectory = new TCHAR[MAX_PATH+1]; 345 346 VERIFY(::GetCurrentDirectory(MAX_PATH, currentDirectory) > 0); 347 348 mode = env->GetIntField(target, AwtFileDialog::modeID); 349 350 AwtDialog::CheckInstallModalHook(); 351 352 // show the Win32 file dialog 353 if (mode == java_awt_FileDialog_LOAD) { 354 result = ::GetOpenFileName(&ofn); 355 } else { 356 result = ::GetSaveFileName(&ofn); 357 } 358 // Fix for 4181310: FileDialog does not show up. 359 // If the dialog is not shown because of invalid file name 360 // replace the file name by empty string. 361 if (!result) { 362 dlgerr = ::CommDlgExtendedError(); 363 if (dlgerr == FNERR_INVALIDFILENAME) { 364 _tcscpy_s(fileBuffer, bufferLimit, TEXT("")); 365 if (mode == java_awt_FileDialog_LOAD) { 366 result = ::GetOpenFileName(&ofn); 367 } else { 368 result = ::GetSaveFileName(&ofn); 369 } 370 } 371 } 372 373 AwtDialog::CheckUninstallModalHook(); 374 375 DASSERT(env->GetLongField(peer, AwtComponent::hwndID) == 0L); 376 377 AwtDialog::ModalActivateNextWindow(NULL, target, peer); 378 379 VERIFY(::SetCurrentDirectory(currentDirectory)); 380 381 // Report result to peer. 382 if (result) { 383 jint length = multipleMode 384 ? (jint)GetBufferLength(ofn.lpstrFile, ofn.nMaxFile) 385 : (jint)_tcslen(ofn.lpstrFile); 386 jcharArray jnames = env->NewCharArray(length); 387 if (jnames == NULL) { 388 throw std::bad_alloc(); 389 } 390 env->SetCharArrayRegion(jnames, 0, length, (jchar*)ofn.lpstrFile); 391 392 env->CallVoidMethod(peer, AwtFileDialog::handleSelectedMID, jnames); 393 env->DeleteLocalRef(jnames); 394 } else { 395 env->CallVoidMethod(peer, AwtFileDialog::handleCancelMID); 396 } 397 DASSERT(!safe_ExceptionOccurred(env)); 398 } catch (...) { 399 400 env->DeleteLocalRef(target); 401 env->DeleteLocalRef(parent); 402 env->DeleteLocalRef(title); 403 env->DeleteLocalRef(directory); 404 env->DeleteLocalRef(file); 405 env->DeleteLocalRef(fileFilter); 406 env->DeleteGlobalRef(peer); 407 408 delete[] currentDirectory; 409 if (ofn.lpstrFile) 410 delete[] ofn.lpstrFile; 411 throw; 412 } 413 414 env->DeleteLocalRef(target); 415 env->DeleteLocalRef(parent); 416 env->DeleteLocalRef(title); 417 env->DeleteLocalRef(directory); 418 env->DeleteLocalRef(file); 419 env->DeleteLocalRef(fileFilter); 420 env->DeleteGlobalRef(peer); 421 422 delete[] currentDirectory; 423 if (ofn.lpstrFile) 424 delete[] ofn.lpstrFile; 425 } 426 427 BOOL AwtFileDialog::InheritsNativeMouseWheelBehavior() {return true;} 428 429 void AwtFileDialog::_DisposeOrHide(void *param) 430 { 431 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 432 433 jobject self = (jobject)param; 434 435 HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID)); 436 if (::IsWindow(hdlg)) 437 { 438 ::SendMessage(hdlg, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), 439 (LPARAM)hdlg); 440 } 441 442 env->DeleteGlobalRef(self); 443 } 444 445 void AwtFileDialog::_ToFront(void *param) 446 { 447 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 448 449 jobject self = (jobject)param; 450 HWND hdlg = (HWND)(env->GetLongField(self, AwtComponent::hwndID)); 451 if (::IsWindow(hdlg)) 452 { 453 ::SetWindowPos(hdlg, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 454 } 455 456 env->DeleteGlobalRef(self); 457 } 458 459 void AwtFileDialog::_ToBack(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_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 468 } 469 470 env->DeleteGlobalRef(self); 471 } 472 473 // Returns the length of the double null terminated output buffer 474 UINT AwtFileDialog::GetBufferLength(LPTSTR buffer, UINT limit) 475 { 476 UINT index = 0; 477 while ((index < limit) && 478 (buffer[index] != NULL || buffer[index+1] != NULL)) 479 { 480 index++; 481 } 482 return index; 483 } 484 485 /************************************************************************ 486 * WFileDialogPeer native methods 487 */ 488 489 extern "C" { 490 491 JNIEXPORT void JNICALL 492 Java_sun_awt_windows_WFileDialogPeer_initIDs(JNIEnv *env, jclass cls) 493 { 494 TRY; 495 496 AwtFileDialog::parentID = 497 env->GetFieldID(cls, "parent", "Lsun/awt/windows/WComponentPeer;"); 498 DASSERT(AwtFileDialog::parentID != NULL); 499 CHECK_NULL(AwtFileDialog::parentID); 500 501 AwtFileDialog::fileFilterID = 502 env->GetFieldID(cls, "fileFilter", "Ljava/io/FilenameFilter;"); 503 DASSERT(AwtFileDialog::fileFilterID != NULL); 504 CHECK_NULL(AwtFileDialog::fileFilterID); 505 506 AwtFileDialog::setHWndMID = env->GetMethodID(cls, "setHWnd", "(J)V"); 507 DASSERT(AwtFileDialog::setHWndMID != NULL); 508 CHECK_NULL(AwtFileDialog::setHWndMID); 509 510 AwtFileDialog::handleSelectedMID = 511 env->GetMethodID(cls, "handleSelected", "([C)V"); 512 DASSERT(AwtFileDialog::handleSelectedMID != NULL); 513 CHECK_NULL(AwtFileDialog::handleSelectedMID); 514 515 AwtFileDialog::handleCancelMID = 516 env->GetMethodID(cls, "handleCancel", "()V"); 517 DASSERT(AwtFileDialog::handleCancelMID != NULL); 518 CHECK_NULL(AwtFileDialog::handleCancelMID); 519 520 AwtFileDialog::checkFilenameFilterMID = 521 env->GetMethodID(cls, "checkFilenameFilter", "(Ljava/lang/String;)Z"); 522 DASSERT(AwtFileDialog::checkFilenameFilterMID != NULL); 523 CHECK_NULL(AwtFileDialog::checkFilenameFilterMID); 524 525 AwtFileDialog::isMultipleModeMID = env->GetMethodID(cls, "isMultipleMode", "()Z"); 526 DASSERT(AwtFileDialog::isMultipleModeMID != NULL); 527 CHECK_NULL(AwtFileDialog::isMultipleModeMID); 528 529 /* java.awt.FileDialog fields */ 530 cls = env->FindClass("java/awt/FileDialog"); 531 CHECK_NULL(cls); 532 533 AwtFileDialog::modeID = env->GetFieldID(cls, "mode", "I"); 534 DASSERT(AwtFileDialog::modeID != NULL); 535 CHECK_NULL(AwtFileDialog::modeID); 536 537 AwtFileDialog::dirID = env->GetFieldID(cls, "dir", "Ljava/lang/String;"); 538 DASSERT(AwtFileDialog::dirID != NULL); 539 CHECK_NULL(AwtFileDialog::dirID); 540 541 AwtFileDialog::fileID = env->GetFieldID(cls, "file", "Ljava/lang/String;"); 542 DASSERT(AwtFileDialog::fileID != NULL); 543 CHECK_NULL(AwtFileDialog::fileID); 544 545 AwtFileDialog::filterID = 546 env->GetFieldID(cls, "filter", "Ljava/io/FilenameFilter;"); 547 DASSERT(AwtFileDialog::filterID != NULL); 548 549 CATCH_BAD_ALLOC; 550 } 551 552 JNIEXPORT void JNICALL 553 Java_sun_awt_windows_WFileDialogPeer_setFilterString(JNIEnv *env, jclass cls, 554 jstring filterDescription) 555 { 556 TRY; 557 558 AwtFileDialog::Initialize(env, filterDescription); 559 560 CATCH_BAD_ALLOC; 561 } 562 563 JNIEXPORT void JNICALL 564 Java_sun_awt_windows_WFileDialogPeer__1show(JNIEnv *env, jobject peer) 565 { 566 TRY; 567 568 /* 569 * Fix for 4906972. 570 * 'peer' reference has to be global as it's used further in another thread. 571 */ 572 jobject peerGlobal = env->NewGlobalRef(peer); 573 574 if (!AwtToolkit::GetInstance().PostMessage(WM_AWT_INVOKE_METHOD, 575 (WPARAM)AwtFileDialog::Show, (LPARAM)peerGlobal)) { 576 env->DeleteGlobalRef(peerGlobal); 577 } 578 579 CATCH_BAD_ALLOC; 580 } 581 582 JNIEXPORT void JNICALL 583 Java_sun_awt_windows_WFileDialogPeer__1dispose(JNIEnv *env, jobject peer) 584 { 585 TRY_NO_VERIFY; 586 587 jobject peerGlobal = env->NewGlobalRef(peer); 588 589 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_DisposeOrHide, 590 (void *)peerGlobal); 591 // peerGlobal ref is deleted in _DisposeOrHide 592 593 CATCH_BAD_ALLOC; 594 } 595 596 JNIEXPORT void JNICALL 597 Java_sun_awt_windows_WFileDialogPeer__1hide(JNIEnv *env, jobject peer) 598 { 599 TRY; 600 601 jobject peerGlobal = env->NewGlobalRef(peer); 602 603 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_DisposeOrHide, 604 (void *)peerGlobal); 605 // peerGlobal ref is deleted in _DisposeOrHide 606 607 CATCH_BAD_ALLOC; 608 } 609 610 JNIEXPORT void JNICALL 611 Java_sun_awt_windows_WFileDialogPeer_toFront(JNIEnv *env, jobject peer) 612 { 613 TRY; 614 615 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_ToFront, 616 (void *)(env->NewGlobalRef(peer))); 617 // global ref is deleted in _ToFront 618 619 CATCH_BAD_ALLOC; 620 } 621 622 JNIEXPORT void JNICALL 623 Java_sun_awt_windows_WFileDialogPeer_toBack(JNIEnv *env, jobject peer) 624 { 625 TRY; 626 627 AwtToolkit::GetInstance().SyncCall(AwtFileDialog::_ToBack, 628 (void *)(env->NewGlobalRef(peer))); 629 // global ref is deleted in _ToBack 630 631 CATCH_BAD_ALLOC; 632 } 633 634 int ScaleDownX(int x, HWND hwnd) { 635 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(hwnd); 636 Devices::InstanceAccess devices; 637 AwtWin32GraphicsDevice* device = devices->GetDevice(screen); 638 return device == NULL ? x : device->ScaleDownX(x); 639 } 640 641 int ScaleDownY(int y, HWND hwnd) { 642 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(hwnd); 643 Devices::InstanceAccess devices; 644 AwtWin32GraphicsDevice* device = devices->GetDevice(screen); 645 return device == NULL ? y : device->ScaleDownY(y); 646 } 647 648 jobject AwtFileDialog::_GetLocationOnScreen(void *param) 649 { 650 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 651 652 jobject result = NULL; 653 HWND hwnd = (HWND)env->GetLongField((jobject)param, AwtComponent::hwndID); 654 655 if (::IsWindow(hwnd)) 656 { 657 RECT rect; 658 VERIFY(::GetWindowRect(hwnd, &rect)); 659 result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V", 660 ScaleDownX(rect.left, hwnd), ScaleDownY(rect.top, hwnd)); 661 } 662 663 if (result != NULL) 664 { 665 jobject resultRef = env->NewGlobalRef(result); 666 env->DeleteLocalRef(result); 667 return resultRef; 668 } 669 else 670 { 671 return NULL; 672 } 673 } 674 675 /* 676 * Class: sun_awt_windows_WFileDialogPeer 677 * Method: getLocationOnScreen 678 * Signature: ()Ljava/awt/Point; 679 */ 680 JNIEXPORT jobject JNICALL 681 Java_sun_awt_windows_WFileDialogPeer_getLocationOnScreen(JNIEnv *env, 682 jobject peer) { 683 TRY; 684 685 jobject peerRef = env->NewGlobalRef(peer); 686 jobject resultRef = (jobject)AwtToolkit::GetInstance().SyncCall( 687 (void*(*)(void*))AwtFileDialog::_GetLocationOnScreen, (void *)peerRef); 688 env->DeleteGlobalRef(peerRef); 689 690 if (resultRef != NULL) 691 { 692 jobject result = env->NewLocalRef(resultRef); 693 env->DeleteGlobalRef(resultRef); 694 return result; 695 } 696 697 return NULL; 698 699 CATCH_BAD_ALLOC_RET(NULL); 700 } 701 702 } /* extern "C" */