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

Liên hệ QC

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

vba_gpe

Thành viên thường trực
Tham gia
15/12/10
Bài viết
296
Được thích
44
Nghề nghiệp
Thất nghiệp
Gửi anh chị GPE
- Em có dùng chương trình Smart Install Maker để đóng gói một số ứng dụng nhỏ. Sau khi build thành công, em thấy trong màng hình chào mừng của file setup có cái Backgourd và một form để chọn người dùng thao tác. (Cái form trước background).
- Xin hỏi mọi người, nếu em dùng VB6 thì có thể làm được điều này không ạ!

Mong nhận được đóng góp của mọi người.

Cảm ơn anh chị trước.
Trân trọng.
 
Gửi anh chị GPE
- Em có dùng chương trình Smart Install Maker để đóng gói một số ứng dụng nhỏ. Sau khi build thành công, em thấy trong màng hình chào mừng của file setup có cái Backgourd và một form để chọn người dùng thao tác. (Cái form trước background).
- Xin hỏi mọi người, nếu em dùng VB6 thì có thể làm được điều này không ạ!

Mong nhận được đóng góp của mọi người.

Cảm ơn anh chị trước.
Trân trọng.
Hình thù nố ra làm sao? Bạn chụp hình đưa lên đây mới hình dung được chứ
 
Hình thù nố ra làm sao? Bạn chụp hình đưa lên đây mới hình dung được chứ
Em gửi thầy và mọi người hình ảnh tham khảo
Em upload ảnh nãy giờ không được nên đành gửi file nén vậy. Thầy và mọi người xem giúp em nhé.
Cảm ơn thầy.
 

File đính kèm

Lần chỉnh sửa cuối:
Em gửi thầy và mọi người hình ảnh tham khảo
Em upload ảnh nãy giờ không được nên đành gửi file nén vậy. Thầy và mọi người xem giúp em nhé.
Cảm ơn thầy.

Mấy trò này có gì đâu. Người ta cố tình làm thế để "dọa" nhau thôi.
Có thể làm theo nhiều cách. Ví dụ như cách sau đây.

code trong Module1:

Mã:
Private Const PROCESS_TERMINATE As Long = 1
Private Const SPI_GETDESKWALLPAPER As Long = 115
Private Const SPI_SETDESKWALLPAPER As Long = 20
Private Const SW_HIDE = 0
Private Const SW_SHOW = 5
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Declare Function SystemParametersInfo Lib "user32.dll" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As String, ByVal fuWinIni As 
Long) As Long
Private Declare Function EnumWindows Lib "user32.dll" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function ShowWindow Lib "user32.dll" _
(ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" _
(ByVal hwnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) 
As Long
Private Declare Function TerminateProcess Lib "kernel32.dll" _
(ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare Function IsWindowVisible Lib "user32.dll" (ByVal hwnd As Long) As Long

Dim myHandle As Long, list() As Long
Dim filename As String, index As Long

Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
  EnumWindowsProc = 1
  If IsWindowVisible(hwnd) <> 0 And hwnd <> myHandle Then
      [COLOR=#0000ff]' nếu cửa sổ đang hiển thị và không phải của ta thì cho handle của nó vào danh sách
[/COLOR]   index = index + 1
    ReDim Preserve list(1 To index)
    list(index) = hwnd
  End If
End Function

Sub HideWindows(ByVal hwnd As Long)
Dim hWindow As Long, hProc As Long, ProcID As Long, k As Long
    [COLOR=#0000ff]' ghi nhớ handle của cửa sổ của ta
[/COLOR]   myHandle = hwnd
    index = 0
    filename = String(256, Chr(0))
    [COLOR=#0000ff]' đọc và ghi nhớ wallpaper hiện hành[/COLOR]
    SystemParametersInfo SPI_GETDESKWALLPAPER, 256, filename, 0
    [COLOR=#0000ff]' duyệt các cửa sổ top-level có trong system[/COLOR]
    EnumWindows AddressOf EnumWindowsProc, 0
    [COLOR=#0000ff]' giấu các cửa sổ có trong danh sách - các cửa sổ đang hiển thị
[/COLOR]   For k = LBound(list) To UBound(list)
        ShowWindow list(k), SW_HIDE
        Sleep 40
        Do While IsWindowVisible(list(k)) <> 0
            ShowWindow list(k), SW_HIDE
            Sleep 40
        Loop
    Next k
    [COLOR=#0000ff]' đọc handle của dải Start - "đồ" của Explorer[/COLOR]
    hWindow = FindWindow("Shell_TrayWnd", vbNullString)
    If hWindow <> 0 Then
        [COLOR=#0000ff]' đọc  process identifier của Explorer
[/COLOR]       GetWindowThreadProcessId hWindow, ProcID
       [COLOR=#0000ff]' đọc handle của process Explorer[/COLOR]
        hProc = OpenProcess(PROCESS_TERMINATE, 0, ProcID)
        If hProc <> 0 Then
             [COLOR=#0000ff]' "thịt" chú Explorer
[/COLOR]           TerminateProcess hProc, 1
            CloseHandle hProc
        End If
        [COLOR=#0000ff]' lấy ảnh của ta làm hình nền[/COLOR]
        SystemParametersInfo SPI_SETDESKWALLPAPER, 0, _
 App.Path & "\forest.bmp", SPIF_SENDCHANGE
    End If
End Sub

Sub ShowWindows()
Dim k As Long
    [COLOR=#0000ff]' Explorer cũ bị ta "thịt" rồi nên phải "đúc" Explorer mới
[/COLOR]   ShellExecute 0, "open", "explorer.exe", vbNullString, vbNullString, SW_SHOW
   [COLOR=#0000ff]' hiển thị lại các cửa sổ đã bị ẩn[/COLOR]
    For k = LBound(list) To UBound(list)
        ShowWindow list(k), SW_SHOW
    Next k
   [COLOR=#0000ff]' phục hồi lại hình nền cũ[/COLOR]
    SystemParametersInfo SPI_SETDESKWALLPAPER, 0, filename, SPIF_SENDCHANGE
End Sub

code trong Form1:

Mã:
Private Sub Form_Load()
    Call HideWindows(Me.hwnd)
End Sub
Private Sub Form_Unload(Cancel As Integer)
    Call ShowWindows
End Sub

Trong tập tin đính kèm có Project1.exe để chạy ngay. Cũng có cả Project trong VB, nếu ai có VB thì cũng có thể tự compile project

Đã test trên XP Home + SP2 và Win 7 Starter. Tôi chỉ có 2 hđh như thế thôi.
 

File đính kèm

Lần chỉnh sửa cuối:
Cảm ơn thầy Siwtom nhiều lắm.

Cho em hỏi nếu muốn tìm chủ đề tương tự với chủ đề em hỏi (chủ đề hiện nay) trên goole bằng Tiếng Anh thì nên viết như thế nào để cho ra kết quả giải quyết phù hợp với đề tài này. Em tìm với từ khóa "how to make background window behide UserForm in VB6" nhưng vẫn chưa tìm được những kết quả mong muốn. Xin thầy và mọi người giúp đỡ.

Trân trọng cảm ơn thầy và anh chị GPE.
 
Lần chỉnh sửa cuối:
Cảm ơn thầy Siwtom nhiều lắm.

Cho em hỏi nếu muốn tìm chủ đề tương tự với chủ đề em hỏi (chủ đề hiện nay) trên goole bằng Tiếng Anh thì nên viết như thế nào để cho ra kết quả giải quyết phù hợp với đề tài này. Em tìm với từ khóa "how to make background window behide UserForm in VB6" nhưng vẫn chưa tìm được những kết quả mong muốn. Xin thầy và mọi người giúp đỡ.

Trân trọng cảm ơn thầy và anh chị GPE.

Tôi không tìm kiếm nên cũng chả biết từ khóa nào tốt nhất.
Vấn đề thực ra không khó. Cái khó là ý tưởng, là hướng đi, là phân tích và chia nhỏ vấn đề. Nhiều khi bạn tìm
cách giải quyết một vấn đề phức tạp thì chưa chắc tìm thấy nhưng những vấn đề "đơn lẻ" cụ thể thì thường
tìm thấy.
Khi tôi nhìn vào hình của bạn thì tôi thấy 2 vấn đề:
1. Ảnh nền. Ảnh nền thì thường ai cũng có trên màn hình, và không ít người thay đổi hình nền "bằng tay". Vậy
vấn đề bây giờ chỉ là làm bằng code.
Hình nền hả? Thế thì thử tìm xem trong help nói gì. Có ngay một mục "Desktop Window". Tôi click vào thì
thấy như hình dưới.

View attachment 90413


Nhìn chữ đỏ đỏ là biết dùng hàm gì để thay hình nền. Để xem các thông số của hàm và cách dùng thì tôi click
vào SystemParametersInfo. Nhìn vào dòng đỏ đỏ ở hình dưới thì tôi sẽ viết code để test, rồi thì ra ngô ra
khoai hết.

View attachment 90414


2. Form. Để cho Form "bá chủ" trên màn hình thì phải ẩn những cửa sổ khác đi. Window? Thì trong help có
mục window. Hide window, show window? Thì cũng có ngay.
Tất nhiên tôi không phải tìm kiếm nữa vì tôi lập trình bằng Windows API nhiều, đọc help nhiều nên biết rồi.
Trong help có tất cả các mục về ListBox, Combobox, Button, ListView, trỏ text, thông điệp, bộ nhớ đệm v...v
Ví dụ như trong hình dưới bạn thấy có nhiều vấn đề nhỏ. Đọc và thử viết code thôi

View attachment 90415

Nếu bạn chia nhỏ vấn đề thì để giải quyết các chi tiết nhỏ bạn chỉ cần đọc help là đủ. Tôi bây giờ chỉ tìm trên
mạng khi việc sử dụng hàm nào đó thực sự phức tạp, "công nghệ" nâng cao. Cái thời tôi "không biết gì" thì
internet cũng chưa được như hiện nay. Tôi đã đọc nhiều sách và tạp chí về máy tính về lập trình.
Muốn lập trình thực sự thì bạn phải biết về API, biết system nó có cấu trúc như thế nào, cơ cấu hoạt động ra
sao v...v Cái này không phải ngày một ngày hai mà có được. Phải đọc nhiều, thử nghiệm nhiều, tự viết code
nhiều.
 
Cảm ơn thầy rất nhiều.
Em sẽ cố gắng! Mong được chỉ bảo của thầy và mọi người nhiều hơn.

Trân trọng.
 
Mấy trò này có gì đâu. Người ta cố tình làm thế để "dọa" nhau thôi.
Có thể làm theo nhiều cách. Ví dụ như cách sau đây.

...........

Trong tập tin đính kèm có Project1.exe để chạy ngay. Cũng có cả Project trong VB, nếu ai có VB thì cũng có thể tự compile project

Đã test trên XP Home + SP2 và Win 7 Starter. Tôi chỉ có 2 hđh như thế thôi.

Nếu mình "thịt" cái Explorer rồi thì khi bấm vào minimize của form, không có taskbar nên muốn thoát chương trình chỉ có Alt+F4, vậy phải làm sao anh?

Nhìn hình dưới, không biết phải làm sao cho cái form phục hồi:
 

File đính kèm

  • Picture1.jpg
    Picture1.jpg
    37.9 KB · Đọc: 198
Thiết lập form nền cho form chính trong VB6 vaf VBA

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 Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Const WS_BORDER = &H800000
Private Const WS_CAPTION = &HC00000          [COLOR="#008000"]'  WS_BORDER Or WS_DLGFRAME[/COLOR]
Private Const WS_THICKFRAME = &H40000
Private Const WS_DLGFRAME = &H400000
Private Const WS_EX_DLGMODALFRAME = &H1&
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Const GWL_STYLE = (-16)
Private Const GWL_EXSTYLE = (-20)
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const SWP_FRAMECHANGED = &H20        [COLOR="#008000"]'  The frame changed: send WM_NCCALCSIZE[/COLOR]
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Dim hForm As Long

Private Sub Form_Initialize()
   'Lấy handle của form
    #If VBA6 Then [COLOR="#008000"]'Nếu code dùng cho VBA[/COLOR]
        hForm = FindWindow("ThunderDFrame", Me.Caption)
    #Else [COLOR="#008000"]'Trong VB6[/COLOR]
        hForm = hwnd
        [COLOR="#008000"]'BorderStyle = None 'Thiết lập ở chế độ design. Có thể bỏ qua [/COLOR]
    #End If
    [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

Private Sub Form_Load()
    [COLOR="#008000"]'Khi form1 load xong thì mở form2  [/COLOR]
    Form2.Show
End Sub

Trong Form2 code như sau:
Mã:
Private Sub cmdClose_Click()
    [COLOR="#008000"]'Đóng form2 khi nhấn nút "Close"[/COLOR]
    Unload Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
    [COLOR="#008000"]'Khi form2 bị đóng (bởi nhấn vào button "Close" hoặc nút [X] của form) thì kết thúc chương trình[/COLOR]
    End
End Sub

Nếu viết code trong VBA thì chỉ cần chỉnh sửa một chút là được. Tôi viết code cho cả VB6 và VBA trong file đính kèm các bạn có thể tham khảo.
 

File đính kèm

Lần chỉnh sửa cuối:
Nếu mình "thịt" cái Explorer rồi thì khi bấm vào minimize của form, không có taskbar nên muốn thoát chương trình chỉ có Alt+F4, vậy phải làm sao anh?

Nhìn hình dưới, không biết phải làm sao cho cái form phục hồi:
Nghĩa thử phím Windows chưa? (Mình bận quá nên chưa down về thử)
 
Nghĩa thử phím Windows chưa? (Mình bận quá nên chưa down về thử)

Đúng là bấm nút Windows thì nó có hiện ra cái form giống như subform. Theo em nghĩ dù là cái hình nó full screen đi nữa cũng nên chừa lại cái taskbar cho dễ thao tác hen!
 
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ụ.

Tôi không hiểu tại sau lại: "không nên can thiệp vào Background của hệ điều hành"?. Vì chuyện thay đổi nó thì user thực hiện liên tục theo ý thích. Nó đâu phải vấn đề "mạo hiểm" để mà "không nên"? Nếu nói "không cần" thì đúng.
Tôi đã nói là có nhiều cách. Đó chỉ là một cách thôi.
Vì sao tôi chủ ý, cố tình "thịt" Explorer? Vì trên cơ sở hình đính kèm thì thì khó biết cái setup kia nó "bá củ" thực sự hay chỉ "giả tạo". Tôi "thịt" explorer là để setup bá chủ thực sự. Vì nếu không thì vẫn có thể gọi các ct khác, và bấm lá cờ Win thì vẫn mở được Start, vẫn chuyển được sang các ct khác. Tất nhiên thịt Explorer thì vẫn còn gọi được các cửa sổ khác, Ctrl + Alt + Del (Task Manage) rồi nạp Explorer nhưng cũng có thể tắt cả Task Manage.
Nói chung chỉ nhìn hình thôi thì khó biết cái setup kia nó là "duy nhất" hay không. Nếu không cần "bá chủ" thực sự thì xóa đoạn "thịt" Explorer, thế thôi.
Còn chuyện làm hình nền "giả lập" hay thực sự thì cũng tùy theo ý thích mỗi người. Nói chung là có nhiều cách. Tôi đã nói là đó chỉ là một cách thôi.
 
Lần chỉnh sửa cuối:
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).


Nếu viết code trong VBA thì chỉ cần chỉnh sửa một chút là được. Tôi viết code cho cả VB6 và VBA trong file đính kèm các bạn có thể tham khảo.

Với Excel, Có một vấn đề là khi dùng chế độ Userform1.ShowModal = False thì với form2 nó không có cái hiện tượng setfocus ở bất cứ control nào (em thêm 1 textbox), cho dù mình có bắt nó làm nó cũng không!

Cho dù ở form2 em có dùng:
Mã:
Private Sub UserForm_Initialize()
    TextBox1.SetFocus
End Sub

hay ở Form1 em thêm:

Mã:
Private Sub UserForm_Activate()
    UserForm2.Show False
    UserForm2.TextBox1.SetFocus
End Sub

Vậy làm cách nào để mặc định load form lên thì nó setfocus như không có 2 form vậy anh?
 
Đúng là bấm nút Windows thì nó có hiện ra cái form giống như subform. Theo em nghĩ dù là cái hình nó full screen đi nữa cũng nên chừa lại cái taskbar cho dễ thao tác hen!

Tôi cố tình tắt tất cả, kể cả taskbar để setup bá chủ mà. Nếu bạn muốn thì xóa đoạn "thịt" Explorer đi, thế thôi.
 
Tôi cố tình tắt tất cả, kể cả taskbar để setup bá chủ mà. Nếu bạn muốn thì xóa đoạn "thịt" Explorer đi, thế thôi.

Em cũng đã bỏ cái đoạn này:

If hProc <> 0 Then
TerminateProcess hProc, 1
CloseHandle hProc
End If

nhưng hình như nó vẫn bị "thịt" à! Taskbar cũng bị ẩn đi.

Mà Anh có thể làm trên Excel được không, vì em không biết xài VB6.
 
Em cũng đã bỏ cái đoạn này:

If hProc <> 0 Then
TerminateProcess hProc, 1
CloseHandle hProc
End If

nhưng hình như nó vẫn bị "thịt" à! Taskbar cũng bị ẩn đi.

Mà Anh có thể làm trên Excel được không, vì em không biết xài VB6.

Tôi viết thiếu vì vội. Explorer không bị thịt nhưng thanh Start là "đồ" của Explorer mà tôi cũng đã ẩn đi. Cần phải kiểm tra trong EnumWindowsProc xem nếu handle hiện tìm thấy có phải là của Shell_TrayWnd không (thanh Start) hay của Progman không (có SysListView với các icon trên desktop), nếu đúng thì KHÔNG thêm vào danh sách để ẩn.
Nhưng làm như thế thì không đúng với dụng ý của tôi. Tôi nhìn hình của người hỏi không thấy thanh Start nên kết luận:
1. Hoặc setup ẩn toàn bộ và bá chủ kiểu: hãy đi "tới cùng" hoặc thoát để trở về Explorer
2. Hoặc thanh Start không nhìn thấy (nhưng không bị ẩn) do cái "hình - form" kia được show MAX và thanh Start không ở chế độ "Always on top"
Tôi chọn th 1 vì thế ẩn tất cả, từ đó mới đề nghị code kia. Nếu không ẩn gì cả thì cái code kia "vô duyên" quá. Lấy cái code được cố tình "thiết kế" để làm một việc rồi sửa lại để nó không làm việc đó thì có lẽ tôi phải vào "bệnh viện tâm thần" mất thôi.
Vậy nếu không ẩn gì, và cho phép user làm việc tí với setup, chuyển sang cửa sổ khác cũng làm việc tí, rồi lại về setup - cứ như thế mãi, thì đi theo hướng của tôi làm gì? Trong th 2 thì dùng cách của bạn Tuân là được rồi.
 
Với Excel, Có một vấn đề là khi dùng chế độ Userform1.ShowModal = False thì với form2 nó không có cái hiện tượng setfocus ở bất cứ control nào (em thêm 1 textbox), cho dù mình có bắt nó làm nó cũng không!

Cho dù ở form2 em có dùng:
Mã:
Private Sub UserForm_Initialize()
    TextBox1.SetFocus
End Sub

hay ở Form1 em thêm:

Mã:
Private Sub UserForm_Activate()
    UserForm2.Show False
    UserForm2.TextBox1.SetFocus
End Sub

Vậy làm cách nào để mặc định load form lên thì nó setfocus như không có 2 form vậy anh?

Mình đã cố tìm cách nhưng chưa được. Vụ này có vẻ khó, khi nào có time mình sẽ tìm cách sửa. Mà vấn đề về mất focus khi Userform.ShowModal = False có thể cũng là lỗi của VBA. Nếu tạo một Userform thường có đăt ShowModal = False, trong Userform có một TextBox, khi chạy thì có focus tại TextBox nhưng khi đặt con trỏ vào sheet rồi lại bấm vào tiêu đề form (để active) thì mất focus mà đúng ra nó vẫn phải có focus.
 
Thì vẫn thường làm trong hđh Windows thôi, tức Alt + TAB

Em có hướng như vầy nha, không biết Anh giúp được em không.

Em thấy rằng, bằng thủ công mình có thể chọn ẩn Icon trên màn hình:

Picture1.jpg

Rồi sau đó, mình chuyển cái hình của mình làm hình nền.

Vậy Anh có thể giúp em code khi mở file Excel lên thì giấu icon trên màn hình và tất cả các cửa sổ sẽ thu nhỏ (minimum) đương nhiên chỉ có cái file của mình là không bị thu nhỏ, đồng thời hiển thị cái hình của mình làm hình nền.

Sau khi thoát file, mình cho mọi thứ trở lại bình thường. Làm vậy có vướng gì cho anh không?

Cám ơn Anh rất nhiều.
 
Lần chỉnh sửa cuối:
Em có hướng như vầy nha, không biết Anh giúp được em không.

Em thấy rằng, bằng thủ công mình có thể chọn ẩn Icon trên màn hình:

View attachment 90552

Rồi sau đó, mình chuyển cái hình của mình làm hình nền.

Vậy Anh có thể giúp em code khi mở file Excel lên thì giấu icon trên màn hình và tất cả các cửa sổ sẽ thu nhỏ (minimum) đương nhiên chỉ có cái file của mình là không bị thu nhỏ, đồng thời hiển thị cái hình của mình làm hình nền.

Sau khi thoát file, mình cho mọi thứ trở lại bình thường. Làm vậy có vướng gì cho anh không?

Cám ơn Anh rất nhiều.

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ó".
 
Web KT

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

Back
Top Bottom