The key event is not listened by my Flex app. Since it is really simple code, I cannot understand where the problem is...
init() {
stage.addEventListener(KeyboardEvent.KEY_DOWN, escHandler);
}
private function escHandler(event:KeyboardEvent):void {
debugF.text = "ESC pressed";
}
thanks
I'm not sure I fully understand your question, but a lot of the user interaction events (including keyboard) are disabled when Flash is in fullscreen mode. Escape is automatically handled by Flash to exit out of fullscreen. I don't believe it will be passed to your listeners.
Related
we have a C++ application that hosts a flex application in a MFC dialog. Everything works fine, all button pushes etc are passed directly on to flex with no problem at all, except the enter and escape keys, which immediately closes the dialog.
We can trap the enter key, by implementing PreTranslateMessage() or OnOK()
and impede the window closing behavior, but we still have the problem of passing these enter key pushes on to the hosted flex app further.
There is no "default" button on the form or anything like that, perhaps MFC is linking the enter key to the close button in the title bar behind the scenes or something.
Does anyone have any ideas how we can stop MFC from treating the enter key from being a special case.
Thanks a lot for any hints.
Edit: Here is PreTranslateMessage() that mmonem requested.
BOOL CFlexDialog::PreTranslateMessage(MSG* pMsg)
{
if ((pMsg->message == WM_KEYDOWN))
{
if (pMsg->wParam == VK_RETURN)
{
m_ctrlFlex->OnReturnKeyPressed();
return TRUE;
}
}
return __super::PreTranslateMessage(pMsg);
}
But it is not a suitable solution, calling a method in the flex app like that, as it makes life too difficult for the flex developer, it means he must write a special version implementing the return key behavior for every control.
We just want MFC to treat the return and escape keys like every other key.
Remove OnOK() and OnCancel(); PreTransateMessage is enough after considering VK_ESCAPE.
Why don't you use:
m_ctrlFlex->SendMessage(WM_KEYDOWN, VK_RETURN, 0)
instead of
m_ctrlFlex->OnReturnKeyPressed();
in your implementation of PreTranslateMessage ?
MFC command buttons can respond to events even if they do not have the focus.
Have you tried trapping the OnClicked event and OnOk to return nothing?
Example: trap OnClick...
void CMyDialog::OnClickedMyOK()
{
CDialog::OnOK();
}
Then do a no-op in the OnOk()
void CMyDialog::OnOK()
{
}
This should stop the enter key from being processed.
Another approach is "Windows Subclassing." That is, sending messages from one Window Procedure, that is a WindProc() to another WndProc(). This may provide a way without direct intervention. (This is not C++ subclassing.)
Here's a way with MFC Subclassing Edit: Provided a better link.
Search for "Windows / MFC Subclassing" if more info needed.
The flex control/window has a WndProc and your window certainly has a WndProc, Windows Subclassing should work.
New Edit: Here is perhaps a better link for subclassing an ActiveX control.
ActiveX Controls: Subclassing a Windows Control
Subclassing Windows Forms Controls - More .Net-centric.
Notice: In MFC you should see these functions.
CWnd::SubclassDlgItem
CWnd::SubclassWindow
CDialog inherits from CWnd so you will see those two functions as "dialog" functions as well. They are key to making this work. If the flash window is a true window, use SubclassWindow. If it's a control use SubclassDlgItem.
And finally, if nothing else works. A product/library that will hopefully make it easy. EasyHook looks like a product here. EasyHook at CodeProject, you can get all the source code.
If you are having issues handling tabs & enter keys I would recommend you look into using a window instead of a dialog. The dialog adds modal ( if you are using modal ), tabbing & default button handling. If you don't need/want those features, or if they are getting in your way, then don't use a dialog.
If I understand what you are doing, then you want flex to handle tabbing, enter key, and all sorts of other messages. Get the dialog code out of the way. If you still want modal style, then you may have to handle the enable/disabling of parent windows - thats all that windows does when you open a modal dialog.
My application consists of a WebView widget. A mouse click on the widget is not handled by the mousePressEvent() of my application, but by the WebView widget. So, I installed an event filter to receive the events. Now, I get notified of all events, except the mouseReleaseEvent for the right click (Everything works fine for left clicks and mousePressEvent for the right click is also getting registered). I guess it has got something to do with context events getting generated by right clicks (a pop-up menu gets generated). But since I am using a filter, the event should first be sent to me. The following is the code for the event filter
in Jambi, but I hope I can modify an answer given in Qt for Jambi.
public boolean eventFilter(QObject o,QEvent event)
{
if (event.type()==QEvent.Type.MouseButtonPress) // One can call the mousePressEvent() functions from here,which can do this work but speed
{
if (((QMouseEvent)event).button()==Qt.MouseButton.LeftButton)
{
mousebuttontype=1;
clickedorpressed=1;
}
else
if (((QMouseEvent)event).button()==Qt.MouseButton.RightButton)
{
mousebuttontype=2;
System.out.println("right");
}
t1=QTime.currentTime();
t1.start();
}
else
if (event.type()==QEvent.Type.MouseButtonRelease)
{
if (t1.elapsed()>900)
{
switch(mousebuttontype)
{
case 1: browser.back();
break;
case 2: browser.forward();
break;
}
}System.out.println("choda");
}
return false;
}
MY BASIC AIM IS GETTING THE TIME INTERVAL FOR WHICH THE RIGHT CLICK WAS PRESSED. ANY WORKAROUND ?
Some digging around certainly seems to suggest that there may be no right-mouse release event being generated if that is the trigger for a context menu on your particular system. These are conveyed as a QContextMenuEvent.
This Qt Labs post hints about this too.
A work around may be tricky if it is system dependent. Have you tried overriding event() in the QApplication class to see if the event comes through there? Some events don't necessarily get to the children but everything goes through QApplication::event().
Another option for you is, subclass Qwebview and override mouseReleaseEvent event
I've found a fix for this that I dont think will be system dependent.
My particular case was using mouseReleaseEvent in order to catch the events, and use them myself. I didn't get these events.
On all child widgets of the widget that I want to handle the event, I added to the class definition:
protected:
void mouseReleaseEvent(QMouseEvent *event) {event->ignore();}
This overrides the default implementation for context menu's, and sends the mouseReleaseEvent back up the parent chain like it would for other mousebuttons.
http://doc.qt.io/qt-5/qevent.html#ignore
This shows that it will probably propagate to the parent widget. As the link indicates, this fixed it for me at Qt 5.9, but I think it should work for virtually all version.
(I am aware this question is literally 7 years old, but it doesn't contain the fix that I think would be the best fix, and shows up as result 2 on google(qt not getting mouse release event on rightclick). So I think it deserves an up to date answer.)
Without going in to broader implementation explanations, the core problem I needed to solve related to this issue was that I needed to know if a context menu swallowed the right-click so I could ensure some custom state was handled properly. The simplest workaround I was able to find was to implement contextMenuEvent, which gets called after mousePressEvent, to detect if the event was accepted (a context menu was opened somewhere in my QGraphicsScene/Items). Here is a minimal example in Python to demonstrate how the event state might be used:
def contextMenuEvent(self, event):
event.setAccepted(False)
super(MyGraphicsView, self).contextMenuEvent(event)
self.__context_menu_used = event.isAccepted()
Note you can also skip running the the base class contextMenuEvent entirely to block the scene/items from opening a context menu. This is handy if you want to do 3D-DCC-like alt-RMB-zooming without accidentally opening a context menu, e.g.:
def contextMenuEvent(self, event):
# Block context menus if alt is held down
if event.modifiers() & QtCore.Qt.AltModifier:
return
event.setAccepted(False)
super(MyGraphicsView, self).contextMenuEvent(event)
self.__context_menu_used = event.isAccepted()
Can a Flax Air Window (NativeWindow) be modal? how?
I think you need to expand on your use case.
If you want it to be modal, do you want to shut down the entire operating system until this window is handled by the user? I doubt that is possible. Do OSes support that in any way? (Other than when crashing).
If you want to prevent your app from being used while this window is up, don't use NativeWindow use a component with the PopUpManager. It has a modal property when creating the popup.
Another possible way would have been to do something like
private function _onActivate(__e:Event):void
{
if ( _settingsWindow )
{
__e.preventDefault();
_settingsWindow.activate()
}
}
and when you open up your settings window, set everything on the "mainapplications" stage to mouseEnabled = false; mouseChildren = false; and listen for the settingswindow close event to reactivate the mouse enabled and set _settingsWindow to null and mainapplications window to activate again (just to make sure)
I have a website which is built totally in flex.
I want to make a button, on the click of which the browser becomes fullscreen. I am not talking about a flex fullscreen, by which i mean "Application.application.stage.displayState = StageDisplayState.FULL_SCREEN;" I dont want to use this.
The reason, I dont want to use it is, that flash does not supports keyboard on flex-fullscreen. But if i can make the browser fullscreen, it will solve my purpose.
Also i am hoping the same method will be good for all browsers on PC and Mac both.
Use ExternalInterface to call a javascript function for it. Sorry this solution is half-baked so I'm not 100% sure it works..
//In ActionScript
public function fullScreen():void
{
if (ExternalInterface.available)
{
ExternalInterface.call("fullScreen");
}
else
{
//Error
}
}
//In JavaScript
function fullScreen()
{
if (parseInt(navigator.appVersion)>3) {
moveTo(0,0);
resizeTo(screen.availWidth,screen.availHeight);
}
//on older browsers just leave it alone
}
i did the same work using thw solution for which you r saying no, u r saying the keyboard doesn't work, but it's working in ma case
here is the button code :
<mx:Button id="fullscreen" styleName="fullscreen" click="toggleFullScreen();"/>
and here is the function which gets called :-
private function toggleFullScreen():void
{
if(Application.application.stage.displayState == StageDisplayState.NORMAL)
Application.application.stage.displayState = StageDisplayState.FULL_SCREEN;
else if(Application.application.stage.displayState == StageDisplayState.FULL_SCREEN)
Application.application.stage.displayState = StageDisplayState.NORMAL;
}
also there are some files , that u need to copy in the html-template folder:-
i'll send u those files, mail me ankursharma85#in.com, i'll reply u
and yes, when u r in full screen mode, u can press "esc" key to get to the normal mode, and if u want to use keyboard to make fullscreen, then u keyboard events, thats a different story
i hope this helps
tc hav a gr8 time
I'm getting an unusual behavior that I can't seem to get to the bottom of. When I run this, if I move in the swf area it traces normally on mouse move. To be expected.
But it's tracing for the move event when I click anywhere on screen. If I click and drag, it traces as if I were moving in the swf area of the browser.
Here's the code. I've simplified to it's barebones. Just put this in in an empty AS3 project in Flex called "Engine" - sans quotes obviously.
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
[SWF(width='640', height='360', backgroundColor='#888888', frameRate='31')]
public class Engine extends Sprite
{
public function Engine()
{
// Add the mouse handlers
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
public function mouseMoveHandler(evt:MouseEvent):void
{
trace("move");
}
}
}
As a workaround I've add the MOUSE_MOVE one MOUSE_OVER and remove it on MOUSE_OUT. But the behavior still seems quite unusual and I'd be interest in understanding why it's happening.
Can anyone tell me how I can keep the events constrained to the actual stage of the application?
As already mentioned, you can't stop these events from firing. They are triggered until you release the mouse.
What you can do is compare the coordinates of the MouseEvent with the bounds of the stage and ignore those outside.
public function mouseMoveHandler(evt:MouseEvent):void
{
if (evt.stageX >= 0 && evt.stageX <= stage.stageWidth &&
evt.stageY >= 0 && evt.stageY <= stage.stageHeight)
{
trace("move");
}
}
If you click inside your flash movie and drag the mouse outside of it, MOUSE_MOVE event will continue to trigger until you release your mouse. MOUSE_LEAVE will trigger only when you release the mouse outside the player. This is how Flash Player works.
Maybe I'm wrong but I don't think you can change this behaviour.
Ok, This is a known bug that only happens with Mac.
There is a fix here :
http://www.visible-form.com/blog/transformmanager-fix-for-mac-firefox/