Cách tạo Background phía sau một form (3 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Những cái này có thể làm được nhưng nếu làm trong Excel thì rồi cũng có "bệnh" như bạn Tuân nói. Khi Textbox nào đó có Focus nhưng rồi Form mất Focus --> Form lấy lại Focus thì bạn không có trỏ text trong Textbox mà trước đó có Focus.
Bạn Tuân nói: sau khi đặt trỏ chuột vào cell --> click thanh tiêu đề hay Form thì không có trỏ text (caret) trong Textbox. Nhưng không chỉ thế. Bằng bất cứ cách nào bạn làm cho Form mất Focus vd. nhấn "lá cờ Windows" thì sau khi click vào Form bạn không nhìn thấy caret trong text box.
Rõ ràng đây là lỗi của Excel.
Có thể khắc phục nửa vời. Nửa vời vì bạn không khắc phục được lỗi trên nhưng khi Form được show thì bạn có thể trong Activate thực hiện SetFocus vào textbox tùy ý (bạn thử thêm 3 textbox rồi SetFocus vào textbox bất kỳ). Làm như thế nào?
Trong code của bạn Tuân trong Initialize của UserForm1 bạn bỏ dòng "SetParent hForm2, hForm" còn trong Acivate của UserForm2 bạn SetFocus cho textbox. Nếu bạn muốn có caret trong textbox đầu tiên thì bạn chả cần SetFocus làm gì vì "tự nó sẽ có".

Không phải vậy Anh ơi, ý em là đổi desktop background đó mà, không hiện 2 form lên 1 lúc nên ta không cần thiết phải show modal. Chỉ là tạm thời tắt chế độ Icon trên desktop, sau đó thay đổi cái backgound của màn hình bằng cái hình của mình, sau đó, trả lại cái hình cũ của máy rồi hiện lại Icon thôi. Thủ công mình làm cũng được mà, nhưng với code thì em đâu biết làm nên mới hỏi vậy mà Anh.
 
Tôi nghĩ chỉ là có một màn hình nền phủ toàn màn hình thì không nên can thiệp vào Background của hệ điều hành (HĐH), càng không nên "thịt" Explorer của nó (sẽ mất hết các thư mục đang mở, có thể ảnh hưởng tới các tiền trình khác mà HĐH đang phục vụ.

Giải pháp của tôi là tạo 2 form: form1 làm nền, form2 là điều khiển chính, nổi trên form1 (form2 là con của form1).
Trong Form1 code như sau:
Mã:
Option Explicit


Private Sub Form_Initialize()
   'Lấy handle của form
[B]    [COLOR=#ff0000]#[/COLOR]If VBA6 Then [COLOR=#008000]'Nếu code dùng cho VBA[/COLOR]
        hForm = FindWindow("ThunderDFrame", Me.Caption)
    [COLOR=#ff0000]#[/COLOR]Else [COLOR=#008000]'Trong VB6[/COLOR]
        hForm = hwnd
        [COLOR=#008000]'BorderStyle = None 'Thiết lập ở chế độ design. Có thể bỏ qua [/COLOR]
   [COLOR=#ff0000] #[/COLOR]End If[/B]
    [COLOR=#008000]'Loại bỏ tiêu đề, đường viền của form1 [/COLOR]
    SetWindowLong hForm, GWL_STYLE, GetWindowLong(hForm, GWL_STYLE) And Not (WS_BORDER Or WS_CAPTION Or WS_THICKFRAME Or WS_DLGFRAME)
    SetWindowLong hForm, GWL_EXSTYLE, GetWindowLong(hForm, GWL_EXSTYLE) And Not WS_EX_DLGMODALFRAME
    Dim rc As RECT
    [COLOR=#008000]'Lấy độ rộng, cao của màn hình  [/COLOR]
    GetWindowRect GetDesktopWindow, rc
    [COLOR=#008000]'Thiết lập độ rộng, độ cao của form1 cho toàn màn hình  [/COLOR]
    SetWindowPos hForm, 0, rc.Left, rc.Top, rc.Right, rc.Bottom, SWP_FRAMECHANGED
    Form1.Show vbModeless [COLOR=#008000]'Nếu trong VBA phải thiết lập ở chế độ thiết kế (design mode) là Userform1.ShowModal = False [/COLOR]
    [COLOR=#008000]'Tạo quan hệ form2 là con của form1  [/COLOR]
    SetParent Form2.hwnd, hForm
End Sub

Em có một thắc mắc, vì sao có những dấu # ở đằng trước IF? Nó có dụng ý gì vậy?
 
Không phải vậy Anh ơi, ý em là đổi desktop background đó mà, không hiện 2 form lên 1 lúc nên ta không cần thiết phải show modal. Chỉ là tạm thời tắt chế độ Icon trên desktop, sau đó thay đổi cái backgound của màn hình bằng cái hình của mình, sau đó, trả lại cái hình cũ của máy rồi hiện lại Icon thôi. Thủ công mình làm cũng được mà, nhưng với code thì em đâu biết làm nên mới hỏi vậy mà Anh.

Bạn nói là làm thủ công được rồi?
Bạn hãy làm thủ công rồi chụp cái hình mà trong đó UserForm (chỉ UserForm thôi không có cửa sổ Sheet) "ngồi chễm chệ" trên màn hình cho tôi xem mặt mũi chúng như thế nào nhé.
---------
Mà thôi.
Nghĩa xem đúng ý chưa.
Trong Activate tôi setfocus cho textbox2. Nếu cần cho texbox1 thì chả cần setfocus, tự nó có.
--------
À, có một vấn đề như thế này.
1. code chỉ làm việc với UserForm có ShowModal = FALSE
2. Với code hiện thời nếu trong khi UserForm được hiển thị mà ta giải lao tí và chuyển sang làm việc với sheet (click vào Book1.xls trên taskbar) thì cửa sổ sheet nó che hình nền. Nếu ta click vào nút "-" để kéo nó xuống thì UserForm cũng xuống theo. Vậy ta sửa chút code:

a. thêm trong Module1:

Mã:
Private Const SW_SHOW = 5
Public Sub MinimizeApp()
    ShowWindow FindWindow("XLMAIN", Application.Caption), SW_MINIMIZE
    ShowWindow hForm, SW_SHOW
End Sub

b. trong UserForm thêm:

Mã:
Private Sub UserForm_Click()
    MinimizeApp
End Sub

c. Khi làm việc xong với sheet mà muốn "kéo nó xuống" thì click trên Form
 

File đính kèm

Lần chỉnh sửa cuối:
Bạn nói là làm thủ công được rồi?
Bạn hãy làm thủ công rồi chụp cái hình mà trong đó UserForm (chỉ UserForm thôi không có cửa sổ Sheet) "ngồi chễm chệ" trên màn hình cho tôi xem mặt mũi chúng như thế nào nhé.
---------
Mà thôi.
Nghĩa xem đúng ý chưa.
Trong Activate tôi setfocus cho textbox2. Nếu cần cho texbox1 thì chả cần setfocus, tự nó có.
--------
À, có một vấn đề như thế này.
1. code chỉ làm việc với UserForm có ShowModal = FALSE
2. Với code hiện thời nếu trong khi UserForm được hiển thị mà ta giải lao tí và chuyển sang làm việc với sheet (click vào Book1.xls trên taskbar) thì cửa sổ sheet nó che hình nền. Nếu ta click vào nút "-" để kéo nó xuống thì UserForm cũng xuống theo. Vậy ta sửa chút code:

a. thêm trong Module1:

Mã:
Private Const SW_SHOW = 5
Public Sub MinimizeApp()
    ShowWindow FindWindow("XLMAIN", Application.Caption), SW_MINIMIZE
    ShowWindow hForm, SW_SHOW
End Sub

b. trong UserForm thêm:

Mã:
Private Sub UserForm_Click()
    MinimizeApp
End Sub

c. Khi làm việc xong với sheet mà muốn "kéo nó xuống" thì click trên Form

Đúng ý em rồi Anh ơi, phải nói là rất tuyệt vời! Mình chỉ thay màn hình rồi trả lại sẽ tốt hơn mình "thịt" thằng Explorer rồi nuốt không trôi phải "nhả" ra. Khi thịt nó, hình như ta mất luôn kết nối với Net hay sao đó, vì vậy khi trả lại nó sẽ phục hồi, mình có cảm giác chậm và chớp chớp khó chịu. Em chỉ nói hình như thôi, không chắc chắn lắm.

Cám ơn Anh rất nhiều!
 
Em có một thắc mắc, vì sao có những dấu # ở đằng trước IF? Nó có dụng ý gì vậy?

Sử dụng # trước các lệnh để làm việc với môi trường và định hướng biên dịch. Trong ví dụ của mình sử dụng #IF..#Else..#End If để tự động nhận biết đang chạy trong VBA hay môi trường khác (VB6), nếu là VBA thì chạy khối lệnh trong VBA (nếu là môi trường VBA bạn viết code trong nhánh của #Else thì trình biên dịch không làm việc - dù viết lỗi cũng không kiểm tra gì.

Sử dụng phương pháp định hướng biên dịch (sử dụng #) thường với mục đích để viết code dùng chung, đảm bảo tương thích cho từng môi trường. Ví dụ bạn viết code chạy cho VBA, VB6, VBA32-bit, VBA64-bit.

Về ý đồ ẩn biểu tượng, thu nhỏ các cửa sổ có vẻ không ổn đâu, như máy của mình dùng một số ứng dụng chạy thường trú trên Desktop bị biến mất hoặc ẩn đâu đó mà không không phục lại được. Nếu làm ứng dụng phân phối cho nhiều người thì không nên can thiệp làm thay đổi giao diện người dùng của Hệ điều hành. Nếu có thay đổi thì phải hoàn trả ngay sau kthi lệnh đó thực thi xong (trong hàm hoặc thủ tục) chứ không phải đợi thoát ứng dụng.
 
Bạn nói là làm thủ công được rồi?
Bạn hãy làm thủ công rồi chụp cái hình mà trong đó UserForm (chỉ UserForm thôi không có cửa sổ Sheet) "ngồi chễm chệ" trên màn hình cho tôi xem mặt mũi chúng như thế nào nhé.
---------
Mà thôi.
Nghĩa xem đúng ý chưa.

Cho em hỏi thêm một vấn đề, tại sao nó chỉ nhận hình có đuôi *.bmp mà không nhận hình đuôi dạng khác? *.jpg chẳng hạn?

Anh có thể điều chỉnh lại cho em không? Đa dạng đuôi có được không?

Xin cám ơn Anh.
 
Cho em hỏi thêm một vấn đề, tại sao nó chỉ nhận hình có đuôi *.bmp mà không nhận hình đuôi dạng khác? *.jpg chẳng hạn?

Anh có thể điều chỉnh lại cho em không? Đa dạng đuôi có được không?

Xin cám ơn Anh.

JPG và các format khác chỉ là khi "nằm" trên đĩa thôi. Khi đọc vào control (vd. Picture, trong Paint ...) chúng đều được convert sang bitmap.
Về wallpaper thì bạn có thể chọn "bằng tay" tập tin JPG làm hình nền vì sau khi bạn chọn xong thì Windows convert nó sang BMP và "save as" ở chỗ khác với tên "Wallpaper.bmp"
Bạn có thể thấy tận mắt bằng cách: Trong Sub ShowDesktopIcons sau dòng
SystemParametersInfo SPI_GETDESKWALLPAPER, 256, defWallPaper, 0
bạn viết thêm dòng
Debug.Print defWallPaper
Sau khi đọc được defWallPaper thì bạn đi theo đường dẫn và mở tập tin Wallpaper.bmp thì bạn thấy nó chính là ảnh JPG mà bạn đã chọn.
Mỗi lần bạn đổi wallpaper bằng tay thì tập tin JPG bạn chọn được convert sang bitmap và ghi trong thư mục "ấy" với tên wallpaper.bmp. Windows sẽ dùng cái BMP này để làm hình nền.
------------
Nếu bạn muốn chọn JPG cũng được thôi nhưng bạn phải convert nó sang BMP, thế thôi.
Bạn hãy chạy ví dụ sau:

Mã:
Sub Button1_Click()
    Filename = Application.GetOpenFilename("JPG files (*.jpg),*.jpg,GIF files (*.gif),*.gif")
    If Filename <> False Then
        SaveAsBMP Filename
    End If
End Sub

Sub SaveAsBMP(ByVal picFilename As String)
Dim ext As String, pic As IPictureDisp, k As Long
    k = InStrRev(picFilename, ".")
    ext = LCase(Mid(picFilename, k))
    If ext <> ".bmp" Then
        Set pic = LoadPicture(picFilename)
        SavePicture pic, Left(picFilename, k - 1) & ".bmp"
        Set pic = Nothing
    End If
End Sub

Tức khi đã chọn được ảnh rồi thì gọi sub SaveAsBMP và truyền đường dẫn vào. SaveAsBMP sẽ ghi ở cùng thư mục với cùng tên nhưng định dạng là BMP. Bạn có thể thay đổi, vd. thư mục ghi. Khi thay hình nền thì truyền đường dẫn của BMP chứ không phải đường dẫn của ảnh chọn.
Chú ý là SavePicture luôn ghi trên đĩa ở dạng BMP. Vậy nếu bạn gọi:
SavePicture pic, "c:\hichic.TXT"
thì nó vẫn ghi trên đĩa với tên hichic.TXT nhưng thực chất "lõi" là BMP - nếu bạn mở trong HexEditor thì 2 bai đầu sẽ là 42, 4D, tức "BM". Đổi đuôi lại thành hichic.bmp thì mở ra thấy ảnh.
 
Về ý đồ ẩn biểu tượng, thu nhỏ các cửa sổ có vẻ không ổn đâu, như máy của mình dùng một số ứng dụng chạy thường trú trên Desktop bị biến mất hoặc ẩn đâu đó mà không không phục lại được. Nếu làm ứng dụng phân phối cho nhiều người thì không nên can thiệp làm thay đổi giao diện người dùng của Hệ điều hành. Nếu có thay đổi thì phải hoàn trả ngay sau kthi lệnh đó thực thi xong (trong hàm hoặc thủ tục) chứ không phải đợi thoát ứng dụng.

Theo em thấy thì trên desktop khi click phải có mục check Show Desktop Icons nếu bỏ check thì không nhìn thấy Icons nữa, khi cần thì mình lại check, như thế theo em nghĩ thì cũng đâu ảnh hưởng gì đến tất cả các chương trình đang chạy hay không chạy đâu Anh? Dùng code để thực hiện nó chỉ là biên dịch lại cái công đoạn mình check thủ công thôi. Không biết điều gì khiến Anh nghĩ là ảnh hưởng đến các chương trình đang chạy vậy? Không biết nên muốn hỏi cho rõ anh à.
 
Tức khi đã chọn được ảnh rồi thì gọi sub SaveAsBMP và truyền đường dẫn vào. SaveAsBMP sẽ ghi ở cùng thư mục với cùng tên nhưng định dạng là BMP. Bạn có thể thay đổi, vd. thư mục ghi. Khi thay hình nền thì truyền đường dẫn của BMP chứ không phải đường dẫn của ảnh chọn.
Chú ý là SavePicture luôn ghi trên đĩa ở dạng BMP. Vậy nếu bạn gọi:
SavePicture pic, "c:\hichic.TXT"
thì nó vẫn ghi trên đĩa với tên hichic.TXT nhưng thực chất "lõi" là BMP - nếu bạn mở trong HexEditor thì 2 bai đầu sẽ là 42, 4D, tức "BM". Đổi đuôi lại thành hichic.bmp thì mở ra thấy ảnh.

Một thắc mắc nữa là khi chạy thủ tục:

PHP:
Sub HideIcon()
    ShowDesktopIcons False
End Sub

Em thử click phải trên desktop, về bản chất thì nó đã không hiện Icon, nhưng trên Menu thì nút Show Desktop Icons nó vẫn check, vậy tại sao có hiện tượng này vậy, xin Anh vui lòng giải thích ạ.

Khi bấm thử vào nó thì nó lại tiếp tục Hide một lần nữa, tức là khi ta cho hiện lại màn hình cũ thì Icons không được hiện ra.
 

File đính kèm

  • Picture1.jpg
    Picture1.jpg
    61.7 KB · Đọc: 62
Theo em thấy thì trên desktop khi click phải có mục check Show Desktop Icons nếu bỏ check thì không nhìn thấy Icons nữa, khi cần thì mình lại check, như thế theo em nghĩ thì cũng đâu ảnh hưởng gì đến tất cả các chương trình đang chạy hay không chạy đâu Anh? Dùng code để thực hiện nó chỉ là biên dịch lại cái công đoạn mình check thủ công thôi. Không biết điều gì khiến Anh nghĩ là ảnh hưởng đến các chương trình đang chạy vậy? Không biết nên muốn hỏi cho rõ anh à.

Ah, mình thấy các cửa sổ bị thu nhỏ hoặc ẩn trong hàm "Enum....". Thói quen của người dùng Windows thường thao tác trên nhiều cửa sổ một lúc, đăng chạy cái A thì lại chạy cái B nên nếu ẩn các icon để phục vụ cho App của mình thì có không hợp lý lắm.
 
Ah, mình thấy các cửa sổ bị thu nhỏ hoặc ẩn trong hàm "Enum....". Thói quen của người dùng Windows thường thao tác trên nhiều cửa sổ một lúc, đăng chạy cái A thì lại chạy cái B nên nếu ẩn các icon để phục vụ cho App của mình thì có không hợp lý lắm.

Tất cả các cửa sổ chỉ bị kéo xuống thanh tác vụ chứ không bị ẩn và người dùng luôn có thể kích hoạt chúng - các cửa sổ không bị ẩn mà chỉ bị minimize.
Chỉ có ListView với các icons bị ẩn.

Chắc chắn việc kéo các cửa sổ xuống thanh tác vụ mỗi ngày mỗi người làm 1000 lần. Việc thay hình nền, ẩn icons cũng là việc bình thường mà thỉnh thoảng mỗi người vẫn làm. Nếu việc làm đó nguy hiểm thì Windows không bao giờ tạo khả năng cho user như thế.

Nói cho cùng đã là phần mềm thì nó có thể chạy trên nền, chạy ẩn. Và mọi thao tác: mở ghi tập tin, thư mục, nối mạng, khởi động máy in v...v tóm lại mọi việc đều làm được mà chả cần tới cái gọi là Explorer.
Explorer cần cho user, nó tạo ra giao diện để cho người dùng có thể mở tập tin, ứng dụng, duyệt web, in ấn v...v
Người dùng cần Explorer chứ phần mềm đâu có cần trung gian của Explorer?
Tôi chưa gặp phần mềm kỳ cục kiểu: muốn chạy được thì thư mục abc phải mở hay cửa sổ xyz phải không bị minimized, hoặc hình nền phải là thế này thế này.

Ẩn các cửa sổ đúng không phải là cách "an toàn" tuyệt đối nhưng còn chuyện thay màn hình, ẩn icons, minimize các cửa sổ thì bản thân Windows tạo điều kiện thuận lợi nhất cho user thực hiện, và bản thân user cũng thao tác liên tục (về minimize các cửa sổ, còn thay hình nền thì thỉnh thoảng thôi)

Cuối cùng thì bạn nên để ý tới một điều: Cái ẩn icons là do người dùng cụ thể (ở đây là Nghĩa) muốn như thế. Code được viết cho khách cụ thể, theo đơn đặt hàng cụ thể, với yêu cầu cụ thể. Khách hàng này trên máy của mình thì vừa là người dùng vừa là chủ nên họ muốn thế nào thì kệ họ mà. Người dùng biết "phần mềm" làm gì mà vẫn kích hoạt thì có nghĩa là họ kích hoạt có ý thức, chủ ý, và sẵn sàng chấp nhận những hạn chế có thể có do phần mềm gây ra.
Bản thân tôi cũng đã nói ngay từ bài đầu là người ta bầy ra lắm trò cũng chỉ là cố tình làm thế để phô trương cái gì đấy, "dọa" ai đấy. Vì nói cho cùng thì nếu hình nền đó là cần thiết (logo, e-mail, web ...) thì vẫn có thể làm 1 Form to bằng màn hình và ảnh thì làm hình nền trong Form. Cứ đâu phải Form "nằm" trên hình?
 
Thực ra qua bài viết của anh thì các thành viên cũng biết thêm các kỹ thuật can thiệp Desktop,...cũng là học hỏi. Em chỉ góp ý với Nghĩa là thế vì thực sự máy em có các cửa sổ của ứng dụng chạy trên Desktop (không phải loại Window có title) bị thu nhỏ không thể khôi phục lại bằng chuột.
 
Một thắc mắc nữa là khi chạy thủ tục:

PHP:
Sub HideIcon()
    ShowDesktopIcons False
End Sub

Em thử click phải trên desktop, về bản chất thì nó đã không hiện Icon, nhưng trên Menu thì nút Show Desktop Icons nó vẫn check, vậy tại sao có hiện tượng này vậy, xin Anh vui lòng giải thích ạ.

Ta khởi động ở trạng thái mà Show Desktop Icons được chọn.
Sau khi mở Form thì mặc dù icons bị dấu đi nhưng "Show Desktop Icons" vẫn được chọn. Vì ta tự ẩn SysListView đi nhưng ta có báo cho system biết đâu?

Khi bấm thử vào nó thì nó lại tiếp tục Hide một lần nữa, tức là khi ta cho hiện lại màn hình cũ thì Icons không được hiện ra.

Vì đối với nó thì "Show Desktop Icons" vẫn đang được chọn, vậy nó ẩn đi và bỏ chọn "Show Desktop Icons" là "hợp lý" rồi.
Theo tôi nếu bạn thay đổ trạng thái của "Show Desktop Icons" (đang chọn sang bỏ hoặc đang bỏ sang chọn) thì trước khi đóng Form cần trả về như cũ. Vì nếu bạn bỏ chọn "Show Desktop Icons" thì làm sao bạn đòi system phải hiển thị icons? Vì code chỉ hiển thị lại SysListView. Vị ListView này làm việc ở chế độ Report, tức hiển thị icons và text. Code hiển thị ListView nhưng nó có hiển thị icons hay không thì có lẽ nó dựa vào trạng thái "Show Desktop Icons" mà bạn đã đổi sang bỏ chọn rồi còn gì.
Tôi ẩn ông A thì dĩ nhiên không nhìn thấy huy chương ông ta đang đeo trên ngực. Nhưng hiển thị lại ông A cũng không đồng nghĩa với chuyện sẽ nhìn thấy huy chương trên ngực ông A. Vì đeo hay không do ông A quyết định và có thể một lúc trước đó ông ta đã ẩn huy chương vào túi rồi.
 
Ta khởi động ở trạng thái mà Show Desktop Icons được chọn.
Sau khi mở Form thì mặc dù icons bị dấu đi nhưng "Show Desktop Icons" vẫn được chọn. Vì ta tự ẩn SysListView đi nhưng ta có báo cho system biết đâu?



Vì đối với nó thì "Show Desktop Icons" vẫn đang được chọn, vậy nó ẩn đi và bỏ chọn "Show Desktop Icons" là "hợp lý" rồi.
Theo tôi nếu bạn thay đổ trạng thái của "Show Desktop Icons" (đang chọn sang bỏ hoặc đang bỏ sang chọn) thì trước khi đóng Form cần trả về như cũ. Vì nếu bạn bỏ chọn "Show Desktop Icons" thì làm sao bạn đòi system phải hiển thị icons? Vì code chỉ hiển thị lại SysListView. Vị ListView này làm việc ở chế độ Report, tức hiển thị icons và text. Code hiển thị ListView nhưng nó có hiển thị icons hay không thì có lẽ nó dựa vào trạng thái "Show Desktop Icons" mà bạn đã đổi sang bỏ chọn rồi còn gì.
Tôi ẩn ông A thì dĩ nhiên không nhìn thấy huy chương ông ta đang đeo trên ngực. Nhưng hiển thị lại ông A cũng không đồng nghĩa với chuyện sẽ nhìn thấy huy chương trên ngực ông A. Vì đeo hay không do ông A quyết định và có thể một lúc trước đó ông ta đã ẩn huy chương vào túi rồi.

Có một lần em nhớ man mác đã đọc bài của ai đó đã dùng API can thiệp vào cái gì đó của hệ thống hay Excel gì đó, mà khi đang thực hiện thì cái nút trên menu đó dấu mark vẫn còn đó, song nó lại Enable = False vì thế không thể can thiệp thủ công khi đang chạy thủ tục được. Sau khi chạy thủ tục xong thì nó tự reset lại như ban đầu. Nhưng em nghĩ cái này cũng chỉ là tiểu tiết, quan trọng là em học được từ Anh và anh Tuân việc can thiệp vào hệ thống như thế nào, cách giải quyết ra sao v.v...

Thực ra qua bài viết của anh thì các thành viên cũng biết thêm các kỹ thuật can thiệp Desktop,...cũng là học hỏi. Em chỉ góp ý với Nghĩa là thế vì thực sự máy em có các cửa sổ của ứng dụng chạy trên Desktop (không phải loại Window có title) bị thu nhỏ không thể khôi phục lại bằng chuột.

Có thể anh Tuân nói đúng, khi em thử thủ tục Minimize ở WinXP thì cảm giác nó hoàn hảo, nhưng với Win7 nó có một vấn đề là form nổi lên đồng thời nổi lên thêm một thanh lạ trên màn hình vì vậy cũng ngại khi sử dụng thủ tục này, nhìn hình có thể giải thích được vấn đề gì đang xảy ra không ạ?
 

File đính kèm

  • ThanhLa.jpg
    ThanhLa.jpg
    104.3 KB · Đọc: 67
Nhìn Video chúng ta thấy rõ ràng là bị lỗi do "thu nhỏ tất cả các cửa sổ":

[video=youtube_share;x3UgROOtTvE]http://youtu.be/x3UgROOtTvE[/video]



Vấn đề trên bị phát sinh là do thủ tục này:

PHP:
EnumWindows FuncPtr(AddressOf EnumWindowsProc), 0


Em thấy rằng ngoài cách thu nhỏ của Anh thì còn có nhiều cách khác, như:

PHP:
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Sub MinimumAllWindow()
    Call keybd_event(&H5B, 0, 0, 0)
    Call keybd_event(&H4D, 0, 0, 0)
    Call keybd_event(&H5B, 0, &H2, 0)
End Sub

Nhưng cách này không thể làm cho con trỏ setfocus trên form được. Vì thế theo em chọn cách dưới đây, tạm thời em cho rằng nó ổn định và setfocus trên form như ý:

PHP:
Sub WindowMinAll()
    CreateObject("Shell.Application").MinimizeAll
    Application.Wait Now + TimeValue("00:00:01")
End Sub

Qua đó, thủ tục khi load form như sau:

PHP:
Private Sub UserForm_Initialize()
      ShowDesktopIcons False
      hForm = FindWindow("ThunderDFrame", UserForm1.Caption)
      Call WindowMinAll
End Sub

Và thoát form thì màn hình excel sẽ trở về trạng thái ban đầu:

PHP:
Private Sub UserForm_Terminate()
      ShowDesktopIcons True
      Application.WindowState = xlMaximized
End Sub

Không biết em làm như vậy có hợp lý không, xin cho em lời khuyên.
 

File đính kèm

Web KT

Bài viết mới nhất

Back
Top Bottom