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_MenuBar.h" 27 #include "awt_Frame.h" 28 29 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. 30 */ 31 32 /***********************************************************************/ 33 // struct for _AddMenu() method 34 struct AddMenuStruct { 35 jobject menubar; 36 jobject menu; 37 }; 38 /************************************************************************ 39 * AwtMenuBar fields 40 */ 41 42 jmethodID AwtMenuBar::getMenuMID; 43 jmethodID AwtMenuBar::getMenuCountMID; 44 45 46 /************************************************************************ 47 * AwtMenuBar methods 48 */ 49 50 51 AwtMenuBar::AwtMenuBar() { 52 m_frame = NULL; 53 } 54 55 AwtMenuBar::~AwtMenuBar() 56 { 57 } 58 59 void AwtMenuBar::Dispose() 60 { 61 if (m_frame != NULL && m_frame->GetMenuBar() == this) { 62 m_frame->SetMenuBar(NULL); 63 } 64 m_frame = NULL; 65 66 AwtMenu::Dispose(); 67 } 68 69 LPCTSTR AwtMenuBar::GetClassName() { 70 return TEXT("SunAwtMenuBar"); 71 } 72 73 /* Create a new AwtMenuBar object and menu. */ 74 AwtMenuBar* AwtMenuBar::Create(jobject self, jobject framePeer) 75 { 76 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 77 78 jobject target = NULL; 79 AwtMenuBar* menuBar = NULL; 80 81 try { 82 if (env->EnsureLocalCapacity(1) < 0) { 83 return NULL; 84 } 85 86 /* target is a java.awt.MenuBar */ 87 target = env->GetObjectField(self, AwtObject::targetID); 88 JNI_CHECK_NULL_GOTO(target, "null target", done); 89 90 menuBar = new AwtMenuBar(); 91 92 SetLastError(0); 93 HMENU hMenu = ::CreateMenu(); 94 // fix for 5088782 95 if (!CheckMenuCreation(env, self, hMenu)) 96 { 97 env->DeleteLocalRef(target); 98 return NULL; 99 } 100 101 menuBar->SetHMenu(hMenu); 102 103 menuBar->LinkObjects(env, self); 104 if (framePeer != NULL) { 105 PDATA pData; 106 JNI_CHECK_PEER_GOTO(framePeer, done); 107 menuBar->m_frame = (AwtFrame *)pData; 108 } else { 109 menuBar->m_frame = NULL; 110 } 111 } catch (...) { 112 env->DeleteLocalRef(target); 113 throw; 114 } 115 116 done: 117 if (target != NULL) { 118 env->DeleteLocalRef(target); 119 } 120 121 return menuBar; 122 } 123 124 HWND AwtMenuBar::GetOwnerHWnd() 125 { 126 AwtFrame *myFrame = m_frame; 127 if (myFrame == NULL) 128 return NULL; 129 else 130 return myFrame->GetHWnd(); 131 } 132 133 void AwtMenuBar::SendDrawItem(AwtMenuItem* awtMenuItem, 134 DRAWITEMSTRUCT& drawInfo) 135 { 136 awtMenuItem->DrawItem(drawInfo); 137 } 138 139 void AwtMenuBar::SendMeasureItem(AwtMenuItem* awtMenuItem, 140 HDC hDC, MEASUREITEMSTRUCT& measureInfo) 141 { 142 awtMenuItem->MeasureItem(hDC, measureInfo); 143 } 144 145 int AwtMenuBar::CountItem(jobject menuBar) 146 { 147 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 148 jint nCount = env->CallIntMethod(menuBar, AwtMenuBar::getMenuCountMID); 149 DASSERT(!safe_ExceptionOccurred(env)); 150 151 return nCount; 152 } 153 154 AwtMenuItem* AwtMenuBar::GetItem(jobject target, long index) 155 { 156 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 157 if (env->EnsureLocalCapacity(2) < 0) { 158 return NULL; 159 } 160 161 jobject menu = env->CallObjectMethod(target, AwtMenuBar::getMenuMID,index); 162 DASSERT(!safe_ExceptionOccurred(env)); 163 164 jobject menuItemPeer = GetPeerForTarget(env, menu); 165 PDATA pData; 166 JNI_CHECK_PEER_RETURN_NULL(menuItemPeer); 167 AwtMenuItem* awtMenuItem = (AwtMenuItem*)pData; 168 169 env->DeleteLocalRef(menu); 170 env->DeleteLocalRef(menuItemPeer); 171 172 return awtMenuItem; 173 } 174 175 void AwtMenuBar::DrawItem(DRAWITEMSTRUCT& drawInfo) 176 { 177 DASSERT(drawInfo.CtlType == ODT_MENU); 178 AwtMenu::DrawItems(drawInfo); 179 } 180 181 void AwtMenuBar::MeasureItem(HDC hDC, 182 MEASUREITEMSTRUCT& measureInfo) 183 { 184 DASSERT(measureInfo.CtlType == ODT_MENU); 185 AwtMenu::MeasureItem(hDC, measureInfo); 186 } 187 188 void AwtMenuBar::AddItem(AwtMenuItem* item) 189 { 190 AwtMenu::AddItem(item); 191 HWND hOwnerWnd = GetOwnerHWnd(); 192 if (hOwnerWnd != NULL) { 193 VERIFY(::InvalidateRect(hOwnerWnd,0,TRUE)); 194 } 195 } 196 197 void AwtMenuBar::DeleteItem(UINT index) 198 { 199 AwtMenu::DeleteItem(index); 200 HWND hOwnerWnd = GetOwnerHWnd(); 201 if (hOwnerWnd != NULL) { 202 VERIFY(::InvalidateRect(hOwnerWnd,0,TRUE)); 203 } 204 ::DrawMenuBar(GetOwnerHWnd()); 205 } 206 207 LRESULT AwtMenuBar::WinThreadExecProc(ExecuteArgs * args) 208 { 209 switch( args->cmdId ) { 210 case MENUBAR_DELITEM: 211 this->DeleteItem(static_cast<UINT>(args->param1)); 212 break; 213 214 default: 215 AwtMenu::WinThreadExecProc(args); 216 break; 217 } 218 return 0L; 219 } 220 221 void AwtMenuBar::_AddMenu(void *param) 222 { 223 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 224 225 AddMenuStruct *ams = (AddMenuStruct *)param; 226 jobject self = ams->menubar; 227 jobject menu = ams->menu; 228 229 AwtMenuBar *m = NULL; 230 231 PDATA pData; 232 JNI_CHECK_PEER_GOTO(self, ret); 233 JNI_CHECK_NULL_GOTO(menu, "null menu", ret); 234 m = (AwtMenuBar *)pData; 235 if (::IsWindow(m->GetOwnerHWnd())) 236 { 237 /* The menu was already created and added during peer creation -- redraw */ 238 ::DrawMenuBar(m->GetOwnerHWnd()); 239 } 240 ret: 241 env->DeleteGlobalRef(self); 242 if (menu != NULL) { 243 env->DeleteGlobalRef(menu); 244 } 245 246 delete ams; 247 } 248 249 /************************************************************************ 250 * MenuBar native methods 251 */ 252 253 extern "C" { 254 255 /* 256 * Class: java_awt_MenuBar 257 * Method: initIDs 258 * Signature: ()V 259 */ 260 JNIEXPORT void JNICALL 261 Java_java_awt_MenuBar_initIDs(JNIEnv *env, jclass cls) 262 { 263 TRY; 264 265 AwtMenuBar::getMenuCountMID = env->GetMethodID(cls, "getMenuCountImpl", "()I"); 266 AwtMenuBar::getMenuMID = env->GetMethodID(cls, "getMenuImpl", 267 "(I)Ljava/awt/Menu;"); 268 DASSERT(AwtMenuBar::getMenuCountMID != NULL); 269 DASSERT(AwtMenuBar::getMenuMID != NULL); 270 271 CATCH_BAD_ALLOC; 272 } 273 274 } /* extern "C" */ 275 276 277 /************************************************************************ 278 * WMenuBarPeer native methods 279 */ 280 281 extern "C" { 282 283 /* 284 * Class: sun_awt_windows_WMenuBarPeer 285 * Method: addMenu 286 * Signature: (Ljava/awt/Menu;)V 287 */ 288 JNIEXPORT void JNICALL 289 Java_sun_awt_windows_WMenuBarPeer_addMenu(JNIEnv *env, jobject self, 290 jobject menu) 291 { 292 TRY; 293 294 AddMenuStruct *ams = new AddMenuStruct; 295 ams->menubar = env->NewGlobalRef(self); 296 ams->menu = env->NewGlobalRef(menu); 297 298 AwtToolkit::GetInstance().SyncCall(AwtMenuBar::_AddMenu, ams); 299 // global refs and ams are deleted in _AddMenu() 300 301 CATCH_BAD_ALLOC; 302 } 303 304 /* 305 * Class: sun_awt_windows_WMenuBarPeer 306 * Method: delMenu 307 * Signature: (I)V 308 */ 309 JNIEXPORT void JNICALL 310 Java_sun_awt_windows_WMenuBarPeer_delMenu(JNIEnv *env, jobject self, 311 jint index) 312 { 313 TRY; 314 315 PDATA pData; 316 JNI_CHECK_PEER_RETURN(self); 317 AwtObject::WinThreadExec(self, AwtMenuBar::MENUBAR_DELITEM, (LPARAM)index); 318 319 CATCH_BAD_ALLOC; 320 } 321 322 /* 323 * Class: sun_awt_windows_WMenuBarPeer 324 * Method: create 325 * Signature: (Lsun/awt/windows/WFramePeer;)V 326 */ 327 JNIEXPORT void JNICALL 328 Java_sun_awt_windows_WMenuBarPeer_create(JNIEnv *env, jobject self, 329 jobject frame) 330 { 331 TRY; 332 333 AwtToolkit::CreateComponent(self, frame, 334 (AwtToolkit::ComponentFactory) 335 AwtMenuBar::Create); 336 PDATA pData; 337 JNI_CHECK_PEER_CREATION_RETURN(self); 338 339 CATCH_BAD_ALLOC; 340 } 341 342 } /* extern "C" */