DefWindowProcW và DefWindowProc khác nhau như thế nào?

Trạng thái
Không mở trả lời sau này.

sieutocviet3

Thành viên mới
Trong topic:
Em thấy @vothanhthu sử dụng DefWindowProcW, và cho hiển thị caption của US là tiếng việt có dấu.
Trong topic:
Tác giả Duy Tân dùng DefWindowProc, và máy tính em không chạy được (Win 7, Office 2013 64bit).

Vậy, anh @vothanhthu cho em hỏi:
1. DefWindowProcW là gì, có tác dụng để làm gì?
2. DefWindowProcW và DefWindowProc khác nhau như thế nào (ý nghĩa, cách dùng)

Em xin cảm ơn.
 

maiban2068

Thành viên mới
Tôi cũng chưa hiểu tại sao bạn @vothanhthu phải dùng nhiều đoạn code đến thế. Nếu chỉ hiển thị Caption UserForm là tiếng Việt thì đoạn code của tác giả Duy Tuân ngắn hơn, đúng là code của tác giả Duy Tuân không chạy được nhưng khi thay DefWindowProc thành DefWindowProcW thì chạy tốt.
Vậy bạn @vothanhthu có thể giải thích ý nghĩa các đoạn code không?
Bạn cần đăng nhập để thấy hình ảnh

File demo:
 

thao nguyen02

Thành viên mới
Mình cũng không hiểu tại sao code của bạn @vothanhthu dài thế để làm gì ạ.
1. Code ban đầu của Duy Tuân:
Mã:
'Author: Nguyen Duy Tuan - Cong ty CP BLUESOFTS
'Website: http://bluesofts.net
Option Explicit
Private Const WM_SETTEXT = &HC
Private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Sub UserForm_Initialize()
    Dim hWnd&, sUnicode$
    hWnd = FindWindow("ThunderDFrame", Caption)  ' Tim HWnd cua UserForm
    sUnicode = Range("A1").Value 'Noi chua chuoi unicode
    DefWindowProc hWnd, WM_SETTEXT, 0, StrPtr(sUnicode)
End Sub
Đúng là code này cũng không hoạt động trên máy mình.

2. Code được chỉnh sửa bởi bạn @maiban2068 chạy tốt:
Mã:
'Author: Nguyen Duy Tuan - Cong ty CP BLUESOFTS
'Website: http://bluesofts.net
Option Explicit
Private Const WM_SETTEXT = &HC
#If Win64 Then
    Private Declare PtrSafe Function DefWindowProcW Lib "user32" (ByVal HWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As LongPtr) As Long
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#Else
    Private Declare Function DefWindowProcW Lib "user32" (ByVal HWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As LongPtr) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If
Private Sub UserForm_Initialize()
    Dim HWnd&, sUnicode$
    HWnd = FindWindow("ThunderDFrame", Caption)  ' Tim HWnd cua UserForm
    sUnicode = Range("A1").Value 'Noi chua chuoi unicode
    DefWindowProcW HWnd, WM_SETTEXT, 0, StrPtr(sUnicode)
End Sub
Tại sao code của bạn @vothanhthu lại phải dài thế để làm gì vậy bạn?
 

tuhocvba

Administrator
Thành viên BQT
Windows Application tiến hành xử lý các thao tác chuột, bàn phím, những sự kiện được phát sinh bởi người dùng (ta gọi đó là sự kiện-event).
Khi xử lý kết thúc, Application sẽ chờ sự kiện tiếp theo phát sinh, nếu có thì sẽ tiếp tục xử lý.
Một chương trình thực thi theo phương thức kiểu như trên, được gọi là chương trình hướng sự kiện.
Chương trình hướng sự kiện sẽ sử dụng các hàm (chương trình) chuyên biệt để xử lý các sự kiện.
Các hàm (chương trình) đó được gọi là Event Handler (xử lý sự kiện).

Event Handler trong Windows Application còn được gọi với tên window procedure.

Khi sự kiện phát sinh window sẽ thông báo bằng tin nhắn (message) tới ứng dụng (Application).
Thông tin tin nhắn sẽ bao gồm chủng loại sự kiện, thời gian phát sinh sự kiện, nơi phát sinh sự kiện...
Tin nhắn được đăng lên hàng đợi tin nhắn (message queue), hoặc cũng có trường hợp được gửi trực tiếp tới window procedure.

DefWindowProc: cung cấp xử lý mặc định cho tin nhắn.
Nguồn 1:
Nguồn 2:
Nguồn 3:

Trên đây là toàn bộ những gì mình tìm hiểu được. Ngoài ra thì mình không biết. Nếu ai biết xin bổ sung và giải thích thêm.
 

vothanhthu

Võ Thành Thứ
@sieutocviet3 Thứ thấy bạn đang có sự hiểu lầm nào đó, Code bên Tuân vẫn đang dùng hàm DefWindowProcW, đây là code của Tuân.
Mã:
Private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Cái các bạn đang chỉnh sửa lại chỉ là sửa khai báo hàm lParam từ dạng Long sang dạng LongPtr cho định dạng 64bit. Bản chất vẫn là hàm DefWindowProcW

@maiban2068 @thao nguyen02 Trong từng thủ tục đều có chú thích Code rất kỹ, từ cách nghĩ đến nguyên lý vận hành Code. Cho nên, Thứ sẽ không lặp lại việc giải thích Code nữa.

Giải thích về việc tại sao Code Tuân ngắn và hay thế, đơn giản là vì... Code của Tuân làm giỏi hơn Thứ.
 
Sửa lần cuối:

thao nguyen02

Thành viên mới
@vothanhthu : Cảm ơn bạn đã trả lời. Thôg số IParam có ý nghĩa gì vậy bạn.
Tôi thấy bạn cũng dùng DefWindowProcW , nếu hiểu bản chất của hàm này thì code phải ngắn đi chứ. Tôi chỉ muốn biết là bạn có hiểu ý nghĩa của hàm này hay không thôi. Tôi không hiểu nên tôi hỏi.
 

vothanhthu

Võ Thành Thứ
nếu hiểu bản chất của hàm này thì code phải ngắn đi chứ
@thao nguyen02 Cái bạn đang không hiểu và muốn hỏi là Thứ có hiểu bản chất hàm DefWindowProcW hay không?. Cách hỏi của bạn cho thấy rằng bạn là người có kiến thức về hàm API, và việc hỏi này có ý nghĩa gì với bạn và với học thuật trong khi bạn đã hiểu rõ hàm này?. Bạn có mục đích gì khi hỏi như vậy ?
 

thao nguyen02

Thành viên mới
@vothanhthu : Thì mục đích là tôi muốn hiểu về ý nghĩa, cách dùng của hàm DefWindowProcW đó bạn. Tôi hiểu thì cần gì phải hỏi, mong bạn chiếu cố, giải thích cho tôi hiểu với.
 

sieutocviet3

Thành viên mới
Về ý nghĩa của FindWindow thì em cũng hiểu:
Tất cả các chương trình, đối tượng chạy trên Windows đều chiếm giữ các vùng nhớ, địa chỉ của các vùng nhớ đó Windows quản lý bằng số nguyên dạng Long. Địa chỉ của các điều khiển này Windows định nghĩa là Handle. Cách viết lHwnd (H-handle; Wnd-window) ám chỉ biến nắm giữ vùng nhớ của đối tượng dạng Long. "Wnd" người lập trình muốn nói rằng vùng nhớ quản lý cửa sổ/Window. Tất cả các ứng dụng, đối tượng điều khiển giao diện, Windows đều đưa nó về khái niệm cửa sổ - Window (đây có thể lý do liên quan tới cái tên hệ điều hành Windows).

Để can thiệp vào các thành phần của cửa sổ thì các hàm truy xuất phải tìm tới địa chỉ vùng nhớ. Giống như muốn gọi điện đến nơi tư vấn các vấn đề chung thì phải gọi số 1080 rồi hỏi gì thì hỏi. 1080 coi là địa chỉ vùng nhớ quản lý một bộ tài nguyên làm việc. Nhà mạng quản lý con số 1080 như là hệ điều hành Windows.

Trong ví dụ của bạn. Muốn thay đổi thuộc tính của cửa sổ Userform thì phải là:
1. Tìm địa chỉ vùng nhớ quản lý cửa sổ:
lHwnd = FindWindow(...). Địa chỉ vùng nhớ nếu tìm được sẽ đc gán vào biến lHwnd.
2. Lấy hoặc thiết lập cửa sổ, các hàm Windows API sẽ dùng địa chỉ cửa sổ làm tham số để truy xuất đúng vùng nhớ-đối tượng. Ví dụ
GetWIndowLong(lHwnd,...)
SetWIndowLong(lHwnd,...)
MessageBox(GetActiveWindow(),..). GetActiveWindow() trả về địa chỉ của cửa sổ cha (hiện tại) - Parent Window để cái hộp thoại MessageBox nằm nổi lên trên.
...
Tóm lại, liên quan đến lập trình cao cấp dùng hàm Windows API là Handle rất quan trọng. Can thiệp đối tượng phải thông qua nó, nếu quá trình lập trình bị lỗi, biến lưu địa chỉ (lHwnd) bị xoá thì mất điều khiển, giống mất hộ chiếu thì đối tượng bạn đang can thiệp "bơ vơ" - Treo luôn :). Thế nên nếu lập trình API cần phải làm một cách hoàn hảo, không đc xảy ra một lỗi nào như sau:
1. Lấy handle: lHwnd=FindWindow(...)
2. Lấy thiết lập cũ: lPrevStyle = GetWindowLong(lHwnd,..)
3. Thiết lập : lOldObject = SetWindowLong(lHwnd,..)
4. Hoàn trả thiết lập cũ: SetWindowLong(lHwnd,.., lPrevStyle)

Các hàm Windows API, ActiveX Controls còn liên quan đến kiến thức Windows 32-bit, 64-bit chính vì thế nhiều ứng dụng Excel gần đây bị lỗi trên Office 64-bit (từ Office 2010 trở lại đây) vì tác giả của các ứng dụng đó chưa lường hết vấn đề lập trình đa môi trường.
Nguồn:
Tuy nhiên hàm DefWindowProcW này thì em cũng không hiểu. Mong được anh @vothanhthu chỉ giáo thêm ạ.
 

thao nguyen02

Thành viên mới
Bạn @vothanhthu đưa link tiếng anh thế này thì mình đầu hàng. Mình không đọc được, cho vào google trans cũng không hiểu gì. Không biết bạn @vothanhthu đọc có hiểu không, bạn giảng bằng tiếng Việt cho mọi người nghe đi ^_^
 

sieutocviet3

Thành viên mới
Sau khi đọc xong thì em vẫn không hiểu anh ạ. Anh hiểu thì giải thích cho em với.
Nếu dựa vào nội dung #9 thì em vẫn chưa hiểu tại sao tác giả Duy Tân lại viết:
Mã:
DefWindowProcW hwnd, &HC, 0, StrPtr(sUnicode)
Tham số đầu tiên hwnd thì em hiểu. Chính là làm việc với cái UserForm mà chúng ta muốn hiển thị Caption là tiếng việt có dấu.
Cái này thì tác giả Tân lấy ở đâu, anh biết không?
Mã:
Const WM_SETTEXT = &HC
Tham số: wParamlParam khác nhau ở cái gì?
Nếu anh biết, giải thích giúp em.
 

vbano1

Admin
Thành viên BQT
Tôi không rõ ý nghĩa, cũng chưa có gì khẳng định tác giả Tân nào đó cũng hiểu ý nghĩa.
Chẳng hạn ta có đoạn code quen thuộc như sau dùng để ghi chữ "abc" vào Notepad (trong điều kiện Notepad đang được mở).
Mã:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_SETTEXT = &HC
Private Sub abc()

    Dim hNotePad As Long
    Dim hEdit As Long

    hNotePad = FindWindow("NotePad", vbNullString)
    hEdit = FindWindowEx(hNotePad, 0, "Edit", vbNullString)
    Call SendMessage(hEdit, WM_SETTEXT, 0, ByVal "abc")

End Sub
Một là hằng số WM_SETTEXT ở trên được sử dụng, có lẽ hàm ý thông báo kiểu tin nhắn là text (tôi không có kiến thức, đoán thôi), tham số thứ 4 là "abc" chính là nội dung truyền vào.
Áp dụng y hệt thứ tự tham số của SendMessage vào DefWindowProcW thì khỏi thắc mắc.
Nguồn:
 

giaiphapvba

Administrator
Thành viên BQT
Chắc là cũng tương tự nhau thôi, nên mọi người tham khảo cái này chắc là sẽ hiểu được:
Mã:
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
           (ByVal hWnd As Long, _
            ByVal Msg As Long, _
            ByVal wParam As Long, _
            ByVal lParam As String) As Long

hWnd: Cua so tiep nhan tin nhan.
Msg: Hang so chi dinh tin nhan.
    WM_IME_CHAR ( &H286) Gui code cua ky tu
    WM_SETTEXT ( &HC) Gui di ky tu string
wParam: Tham so duoc gi di cung voi message
    Truong hop Msg =WM_IME_CHAR: Key code
    Truong hop Msg =WM_SETTEXT: Chua duoc su dung = 0
lParam:    Tham so duoc gui di cung voi message
    Truong hop Msg =WM_IME_CHAR: Chua duoc su dung = 0
    Truong hop Msg =WM_SETTEXT: Con tro toi chuoi ky tu string
Nguồn:
 

thao nguyen02

Thành viên mới
Các thành viên BQT thì cố gắng tìm hiểu để giải thích. Mình phải thừa nhận là bọn Nhật có khi nó viết còn chi tiết tỉ mỉ hơn cả microsoft ấy nhỉ.
Thế mà bạn Thứ không học hỏi, lại cứ mặc định là tớ hiểu rồi (không có căn cứ, tự tưởng tượng) mà không giải thích gì cả. Chán ghê.
 

giaiphapvba

Administrator
Thành viên BQT
Tôi hi vọng các thành viên không sa đà vào bắt bẻ câu chữ, cãi vã không cần thiết. Topic này khóa ở đây, những gì trong khả năng biết của chúng tôi, chúng tôi đã trình bày ra rồi. Nếu ai có phát hiện mới, thì báo lại cho chúng tôi để mở topic. Hoặc các bạn có thể lập topic mới, chia sẻ điều bạn biết.
 
Trạng thái
Không mở trả lời sau này.
Top