Jump to content

wqmeng

Members
  • Content Count

    21
  • Joined

  • Last visited

Everything posted by wqmeng

  1. Hello, Now I working with a FMX app with some sub-forms, now need to switch the forms by clicking the taskbar button of them. The problem is when clicking the button, the main form will show up and the sub-form will be on the front of the main form, if click the main form taskbar button, the sub-form still on the front of the main-form, So would like to know the taskbar button of which form was clicked and then bring the form to be front, let others be behind or hide with their pre-window states. The problem is when click the taskbar button, I could not know which one get clicked, also do not know which form the taskbar button belong to. Anyone knows how to know which taskbar button was clicked and the ownner form it is or any advice? Thank you.
  2. Hello Remy I tried hooking the left mouse button and capturing the thumbnail preview window title, but after trying all possible methods, it is still difficult to get the window text. Use Wnd := WindowFromPoint(MouseInfo^.pt); to try to get the window, then GetWindowText, it is '', then try to use CoCUIAutomation to try to get it, hr := UIAutomation.ElementFromPoint(Point, Element); The element can be obtained with the class name of 'TaskListThumbnailWnd' but no name, try to get the child elements from it, can only get the child elements through Element.FindAll(TreeScope_Children, Condition, children); The class name is 'TaskListOverlayWnd' and there are no other child elements under this child element, and there is no name. I also tried Spy++ and Inspect to find more details, but both of them can't capture the thumbnail preview window well, because it is a pop-up window, when using spy++ you can't get the thumbnail preview window pop-up, if using Inspect, when the thumbnail preview window pops up, it will hide the Inspect window, if you click it, then Inspect will show the result of restoring the window after clicking. I will try more if I can. So if the above function can't get the title of the window, Using a fake main window and try to subclassproc to override WINPROC, maybe we can do it. Thank you very much.
  3. Tried 2, also has problem, If form 3 or other sub-form was hiden by other apps. Click a taskbar button will bring all the hiden sub-form to be front than other app, though the sub-forms will not get the focus. 3 The id seems is the tumbbutton id on the taskbar button pre-view window, not the taskbar button id.
  4. Hello Remy Yes, it is better to let the fmx does as it is. What I find more information about this matter, 1, Find that when VCL, there could setup the sub-form's WndParent to be desktop, that will keep the sub-form as a seperate form as the main form as? So that when delphi restore the main form after clicking the taskbar button, it will not find any child-forms and then active itself instead find a child-form and then restore the child-form if it is active before? So I tried to but not work as VCL app, not sure why. procedure TForm2.FormCreate(Sender: TObject); begin Winapi.Windows.SetParent(FormToHWND(Self), GetDesktopWindow); end; procedure TForm2.FormShow(Sender: TObject); begin Winapi.Windows.SetParent(FormToHWND(Self), GetDesktopWindow); end; 2, If the sub-form works as we expect, so we could hide the main-form and its taskbar button at the whole app life-time? And use the sub-form1 to act as a fake main-form do what the main-form's work? It sound be simple and easy to do just add a new form, and set the new form as the main-form, and min/hide it when the fmx app is running. I tried to create form1(hide), form2(fake-main, when close the app will terminate too), form3. From my test currently, the prolem is the when fmx app start, the form1 will flash before hide it. From another post, seems it is need to modify the FMX source code to avoid the flash of main form. I do not test this on my app yet so do not know if it will cause any other side effect yet. As my app manage other form behavior such as min max fullscreen restore, but I think it should work while need to adjust my codes to work with multi sub-forms. 3, Another find before 2 is the itaskbar interface from win api, In the api, seems it could set a button id, and pass the id back to the message with the LParam, So that we could use our form's wnd as the id and then when the subclassproc get the message, check that LParam and then setfocus on the correct form. I do not know if we could pass the LParam to the setwindowlongptr or some other api could do that, I think there should has. So we could use the api instead itaskbar inerface for the same thing. I do not test this yet. Your posts here are very very helpful. Thank you so much.
  5. Hello Hide the default app taskbar button do active the forms by clicking their taskbar button. While I find that when click the min button to minimize the form1 window, it will hide all the taskbar buttons. And a window's title bar will shows on desktop, zero width and height, this is the default main zero window managed by FMX? Thank you.
  6. Hi Remy, So this is weird, did you change any property of the form or did I miss something in the application configuration? Where do you call InitCommonControlsEx? Can you attach your complete test project here? I have tested my code and the code you posted here. If form2 is active, clicking the form1 taskbar button will still keep form2 active, because I think in FMX, if the main form is hidden by a child form, then FMX should consider that the child form should keep the focus when only one taskbar button for all the FMX forms created and get clicked. This should be the intention of FMX design. Since we added multiple taskbar buttons, we want each button to activate its own form, which will conflict with the design of FMX and therefore cause problems. But as you explained above, it really confuses me. Thank you very much.
  7. You see, if the form1 is not active, after you click the taskbar button form1, the form2 is still the active form, you have to use mouse to click the form1 to get it active. My codes attached. Thank you so much. TestWindowSubClassProc.7z
  8. Hello Remy, I test your codes, it is the same behavior as my, in my test app, the main form and the subform both use the same subclassproc in the unit2, I do not copy it to unit1. I would like to click the taskbar button of form1, then get the form1 to be front and active. If created a form2, and the form2 is already active. Then when you click the taskbar button of form1, You will see that the form1 does not active, the form2 is still the active form. Maybe I do not explain clearly? Thank you very much. 1) click mouse button on a form2, the form2 is active form. form1(main) is not active. 2) click the form1 taskbar button The form1 still not the active form, the form2 always keep active. In my app, I just want the result Click form1 taskbar button, form1 active and to the front. Click form2/form3 taskbar button, form2/form3 active and to the front. Now it works for form2, form3, but not work for form1 when the form1 is not active. Thank you very much.
  9. There is still a problem when clicking the main form taskbar button, if you have already activated the child form, the application will activate the child form instead of the main form. And the main form subclass procedure will not be called but the child form subclass procedure. It seems that the Wnd of the main form taskbar button is not always the same as the main form, it will change to the active child form so that when you click the main form taskbar button, the active child form will be active. On VCL forms, it seems that it can be changed by Application.MainFormOnTaskbar := False, but FMX does not have it. So there should be something in UpdateApplicationHwnd or something else change the main form handle of the taskbar button (main) to be the active child form handle. If we can get the title of the taskbar button that was just clicked intead of the Wnd, maybe we can switch forms more flexibly by the title. Thank you.
  10. Hello Remy Lebeau After InitCommonControlsEx, the SubToolBarSubclassProc works now, Thank you so much. var icc: TInitCommonControlsEx; icc.dwSize := SizeOf(icc); icc.dwICC := ICC_INTERNET_CLASSES or ICC_USEREX_CLASSES or ICC_DATE_CLASSES; InitCommonControlsEx(icc);
  11. Seems the code always return fail result. Not sure why. if not SetWindowSubclass(Wnd, SubToolBarSubclassProc, 1, DWORD_PTR(Self)) then begin LMsg := 'SetWindowSubclass failed! Error code: ' + IntToStr(GetLastError()); end; and the error code always 0.
  12. Hello Remy Lebeau I tried to SetWindowSubclass of the sub-from, but the function SubToolBarSubclassProc never get called. Also I try to replace the old TFMXApplicationService.AddPlatformService; By a new TFMXApplicationService class. And in the class use the function to handle app messages. function TFMXApplicationService.HandleMessage: Boolean; To my suprise that the HandleMessage could not capture any WM_ACTIVATE, WM_NCACTIVATE message from the OS, If I postmessage inside the app, it will invoke. But other messages such as WM_KEYDOWN will process correctly by HandleMessage. Maybe FMX handles the messages and intercepts some messages such as WM_ACTIVATE, WM_NCACTIVATE somewhere else? Thank you.
  13. Hello, when create the form, add this will add the sub-form to the taskbar button. But my problem is above need to know which button get clicked then bring the ownner form to be front. This is useful, if you have 3 or 4 forms in one screen, some of them is maximnized, if you want to bring a behind form to front, you have to min the forms over it, Or click a taskbar button to get it to be front if know how to. Also if one of your form was hiden by other apps, then click the taskbar button could bring your form to be front. Plus the taskbar button has the form's caption, it is much easy to find a hiden form by choose from the taskbar buttons. procedure TSubToolBarForm.FormCreate(Sender: TObject); var Wnd: HWND; ExStyle: LONG_PTR; begin {$IFDEF MSWINDOWS} Wnd := FormToHWND(Self); ExStyle := GetWindowLongPtr(Wnd, GWL_EXSTYLE); SetWindowLong(Wnd, GWL_EXSTYLE, ExStyle or WS_EX_APPWINDOW); {$ENDIF} end; Thank you.
  14. FMX app hanging at start after Windows 11 run for a long time(a few hours). Anybody here notice that when the Windows 11 runs for a while such as a few hours, And my FMX app will be hanging at startup, but I tried to start other apps, there is no such problem. I tested use delphi to create a empty form FMX app, it is still hang when startup, but VCL app will run fine. In this case, the Delphi IDE also has many problems, such the form design window will not load the fmx form and show it, the Object explore and the properties of the form element also do not shows anything, And the popup menu of Delphi IDE will not show the mouse highlight background, and some dialog form of Delphi IDE will not accept mouse click, but if you move keyboard to the buttons on the form, it may(or not) works. I try to open the tools option and User interface and form designer, High DPI, the listbox do not show any listitems in it, and the checkbox show white blank, can not see any words in the text area. And the checkbox could not click/ select or deselect by mouse click. And there seems more problem. But the mostly problem is the FMX app can not run at start up, If I try to start the FMX app repeated by shutdown it in the task manager, After a few retries such as 5 - 20 times, it may startup without any change of the OS. When the problem happens, My Memory shows about 45% (48G total) use, and CPU about 50%( I5 13400F ) usage. Other strange problem the Firefox browser can not copy any text in the web page, and the popup menu of taskbar could not response to mouse too, but you can move up/down button of keyboard to select the popupmenu item and click it to call the command. I am not very sure what's cause this, the probem effect the FMX apps and Delphi IDE, but seems not effect VCL apps. It is worse that the problem happens every day on my PC. Anybody with advice or have a solution? Thank you.
  15. Hello, Yes, Logout and Sign in windows again, will help to get the problem fixed. I tried twice today once the problem happen I log out, and sign in, wait until the problem happen again it does not have to wait so long sometimes just 2~3 hours, it will happen again, try logout and sign in again, the problem gets fixed also, But still do not know what's the matter cause this problem.
  16. Hello Brian Try log out and sign in windows again, and this time the problem get fixed, the app could start correctly, I tried many times. But a few days before I also do the same test (logout and sign in windows), I could remember that it not work. I will try again, but It needs to restart the windows, and waiting until the problem happen, it will take about a few hours, I will report here tomorrow when I do the logout and sign in next time. Thank you very much.
  17. Have tried Win+Ctrl+Shift+B, could see the graphics driver was reloaded, the screen got black and then light again, but then try to start the app, still not work. Same hanging at report the above error 4 times. BTW, the app UI is hanging, but other thread in my app still work. So the main thread to fresh and display the UI should be hang out.
  18. There is no other antivirus installed. This problem will disappear after the windows11 restart, but it will happen again once the OS run a few hours.
  19. This codes, When FSharedMultithread is nil, it will not lock the thread, so that may cause a conflict? Then the app is hangs out? But why the QueryInterface is fail still not known the reason, an OS problem?
  20. After seach, Find this 'Cannot get DirectX SharedMultithread object.' is defined in FMX.Canvas.D2D, const SID_ID2D1Multithread = '{31e6e7bc-e0ff-4d46-8c64-a0a8c41c15d3}'; IID_ID2D1Multithread: TGUID = SID_ID2D1Multithread; SCannotGetSharedMultithreadObject = 'Cannot get DirectX SharedMultithread object.'; The only codes not Succeeded(SharedFactory.QueryInterface(IID_ID2D1Multithread, FSharedMultithread)). Try to query an interface, and failled? class procedure TCanvasD2D.CreateSharedResources; var Prop: TD2D1RenderTargetProperties; Desc: TD3D10_Texture2DDesc; begin inherited; if (FSharedMultithread = nil) and not Succeeded(SharedFactory.QueryInterface(IID_ID2D1Multithread, FSharedMultithread)) then FSharedMultithread := nil; MultithreadEnter; try if FSharedRenderTarget = nil then begin FillChar(Desc, SizeOf(D3D10_TEXTURE2D_DESC), 0); Desc.Format := DXGI_FORMAT_B8G8R8A8_UNORM; Desc.Width := 1; Desc.Height := 1; Desc.MipLevels := 1; Desc.ArraySize := 1; Desc.SampleDesc.Count := 1; Desc.SampleDesc.Quality := 0; Desc.Usage := D3D10_USAGE_DEFAULT; Desc.BindFlags := D3D10_BIND_RENDER_TARGET or D3D10_BIND_SHADER_RESOURCE; if Failed(SharedDevice.CreateTexture2D(Desc, nil, FSharedTexture)) then raise ECannotCreateTexture.CreateFmt(SCannotCreateTexture, [ClassName]); Prop := D2D1RenderTargetProperties(DefaultRenderTargetMode, D2D1PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED)); if Failed(SharedFactory.CreateDxgiSurfaceRenderTarget(FSharedTexture as IDXGISurface, Prop, FSharedRenderTarget)) then raise ECannotCreateRenderTarget.CreateFmt(SCannotCreateRenderTarget, [ClassName]); end; finally MultithreadLeave; end; end;
  21. Hello, Thank you all for your replies, Now I check the output in the IDE with a FMX form with a few buttons on it, and find out if the app hangs up, it will stop at Module Load: d2d1.dll. No Debug Info. Base Address: $78970000. Process TestWin11HangUp.exe (40248) Module Load: DWrite.dll. No Debug Info. Base Address: $5B760000. Process TestWin11HangUp.exe (40248) Debug Output: Cannot get DirectX SharedMultithread object. Process TestWin11HangUp.exe (40248) Debug Output: Cannot get DirectX SharedMultithread object. Process TestWin11HangUp.exe (40248) Debug Output: Cannot get DirectX SharedMultithread object. Process TestWin11HangUp.exe (40248) Debug Output: Cannot get DirectX SharedMultithread object. Process TestWin11HangUp.exe (40248) Thread Exit: Thread ID: 81372. Process TestWin11HangUp.exe (40248) If the App start correctly, Module Load: d2d1.dll. No Debug Info. Base Address: $78970000. Process TestWin11HangUp.exe (42448) Module Load: DWrite.dll. No Debug Info. Base Address: $5B760000. Process TestWin11HangUp.exe (42448) Debug Output: Cannot get DirectX SharedMultithread object. Process TestWin11HangUp.exe (42448) Debug Output: Cannot get DirectX SharedMultithread object. Process TestWin11HangUp.exe (42448) Module Load: igdumdim32.dll. No Debug Info. Base Address: $78E90000. Process TestWin11HangUp.exe (42448) Module Load: igd9trinity32.dll. No Debug Info. Base Address: $79150000. Process TestWin11HangUp.exe (42448) Module Load: igd9dxva32.dll. No Debug Info. Base Address: $7A840000. Process TestWin11HangUp.exe (42448) The different is that the failed app try to get DirectX SharedMultithread object 4 times and without success? Finally, the app form do not shows up correctly. Debug Output: Cannot get DirectX SharedMultithread object. Process TestWin11HangUp.exe (40248) Try to find more information about 'Cannot get DirectX SharedMultithread object', cound not find any useful results. Thank you.
×