Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 3 của 3
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    cần tìm lỗi của dialog box WIN32 API

    thực hiện đảo chuỗi có sử dụng Dialog Box
    bài code mình nghĩ hoàn hảo nhưng kết quả thậm tệ. thậm chí ko xuất hiện dialog button
    Mã:
    #include <Windows.h>
    #include <stdio.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
    HWND TEXTBOX1;
    HWND TEXTBOX2;
    HWND TEXT;
    
    void CreateDialogBox(HWND);
    void RegisterDialogClass(HWND);
    HINSTANCE ghInstance;
    
    void daochuoi(char s[]);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR hCmdLine, int nCmdShow)
    {
    	WNDCLASS wc = { 0 };
    	HWND hwnd;
    	MSG msg;
    
    	wc.lpszClassName = TEXT("HUY");
    	wc.lpfnWndProc = WndProc;
    	wc.hInstance = hInstance;
    	wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    
    	RegisterClass(&wc);
    	hwnd = CreateWindow(wc.lpszClassName, TEXT("HUY"),
    		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    		100, 100, 250, 150,
    		NULL,NULL, hInstance, NULL);
    	ghInstance = hInstance;
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return (int)msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch (msg)
    	{
    	case WM_CREATE:
    	{
    					  RegisterDialogClass(hwnd);
    					  TEXTBOX1 = CreateWindow(TEXT("EDIT"), TEXT(""),
    						  WS_VISIBLE | WS_CHILD | WS_BORDER,
    						  50, 20, 230, 25,
    						  hwnd, (HMENU)2, NULL, NULL);
    					  
    					 TEXT= CreateWindow(TEXT("BUTTON"), TEXT("HOAN DOI"),
    						  WS_CHILD | WS_VISIBLE,
    						  20, 50, 95, 25,
    						  NULL, (HMENU)1, NULL, NULL);
    					  break;
    
    
    	}
    	case WM_COMMAND:
    	{
    					   CreateDialogBox(hwnd);
    					   break;
    	}
    	case WM_DESTROY:
    	{
    					   PostQuitMessage(0);
    					   return 0;
    	}
    	}
    	return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch (msg)
    	{
    	case WM_CREATE:
    		TEXTBOX2 = CreateWindow(TEXT("EDIT"), TEXT(""),
    			WS_BORDER|WS_CHILD|WS_VISIBLE,
    			50, 120, 500, 25,
    			hwnd, (HMENU)3, NULL, NULL);
    		break;
    
    	case WM_COMMAND:
    		if (LOWORD(wParam) == 1)
    		{
    			char szText[MAX_PATH];
    			int iLength = GetWindowTextLength(TEXTBOX1);
    			if (iLength <= 0)
    			{
    				MessageBox(hwnd, TEXT("Error or text is NULL"), TEXT("Huy"), MB_OK | MB_ICONEXCLAMATION); return 0;
    			}
    			else
    			{
    				GetWindowText(TEXTBOX1, szText, iLength + 1);
    				daochuoi(szText);
    				SetWindowText(TEXTBOX2, szText);
    			}
    			return 0;
    		}
    	case WM_CLOSE:
    		DestroyWindow(hwnd);
    		break;
    	}
    	return (DefWindowProc(hwnd, msg, wParam, lParam));
    }
    
    void RegisterDialogClass(HWND hwnd)
    {
    	WNDCLASSEX wc = { 0 };
    	wc.cbSize = sizeof(WNDCLASS);
    	wc.lpfnWndProc = WndProc;
    	wc.hInstance = ghInstance;
    	wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    	wc.lpszClassName = TEXT("DialogClass");
    	RegisterClassEx(&wc);
    }
    
    void CreateDialogBox(HWND hwnd)
    {
    	CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_TOPMOST,
    		TEXT("DialogClass"), TEXT("hoan doi"),
    		WS_VISIBLE|WS_SYSMENU|WS_CAPTION,
    		100, 100, 200, 150,
    		NULL, NULL, ghInstance, NULL);
    }
    
    void daochuoi(char s[])
    {
    	char c;
    	int len = strlen(s);
    	for (int i = 0; i<len / 2; i++)
    	{
    		c = s[i];
    		s[i] = s[len - 1 - i];
    		s[len - 1 - i] = c;
    	}
    
    }
    mong mọi người giúp đỡ [IMG]images/smilies/kiss.gif[/IMG]

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi MHoang
    Cái này có lẽ bạn phải xem lại cơ chế xử lý thông điệp trong chương trình Windows. Không phải ngẫu nhiên mình đề nghị bạn nên xem phần hành chung.

    Trong Windows, phần lớn thời gian chương trình bạn chẳng được ai (hoặc Windows) đoái hoài gì tới, mà nó chỉ nằm im chờ thời thôi. Khi có một sự kiện gì xảy ra, nếu liên quan tới chương trình của bạn thì Windows mới gọi hàm xử lý thông điệp (WndProc) mà bạn đã viết. Ví dụ như người dùng Click trên cửa sổ chương trình bạn, sau nhiều xử lý riêng, Windows mới gọi WndProc với ý nghĩa : "Đây, tao thương chú em mày ngồi chơi xơi nước nhiều quá, tụi người dùng nó Click trên cửa sổ của chú em mày đó, mày tính sao ?". Và Windows giải thích thêm : " Tao đưa cho chú em mày tọa độ mà tụi người dùng nó Click trong tham số lParam nè, hoành độ trong LOWORD(lParam) và tung độ trong HIWORD(lParam) và cả 2 là tính từ góc trái trên của cửa sổ chương trình chú em mày đó."

    Trên nghĩa đó, mình bàn tới thông điệp WM_COMMAND trong WndProc của bạn. Một điều chung nhất là khi xử lý WM_COMMAND bao giờ ta cũng phải xem nó bắt nguồn từ nơi đâu, cái nào ta xử lý thì nên trả về 0, cái nào không xử lý thì trả về DefWindowProc (vẫn có ngoại lệ), tức là ta phải xem các tình huống của lParam và wParam mà WndProc nhận (bạn đâu có muốn khi người dùng muốn nhập một xâu trong Edit nhưng chỉ vừa gõ một chữ thì nhảy ra cái hộp thoại đâu). Giả sử bạn đã qua được WM_COMMAND, mình bàn tiếp tới hàm CreateDialogBox của bạn.

    Bạn chưa phân biệt được đâu là cửa sổ con tự tạo; đâu là cửa sổ hộp thoại; đâu là cửa sổ điều khiển có sẵn.
    _ Khi bạn tạo cửa sổ con tự tạo thì bạn phải đăng ký một lớp cho nó, trong đó bao gồm cả thủ tục xử lý thông điệp riêng, thủ tục này trả về LRESULT.
    _ Khi bạn tạo môt hộp thoại thì bạn phải đưa vào bản mẫu hộp thoại và cái này bạn phải tạo tập tin tài nguyên và chứa bản mẫu trong đó. Trường hợp khác là bạn tự tạo ra bản mẫu mình không nói tới vì nó vượt quá sức của bạn, sau này bạn có thể hỏi tiếp mình sẽ trả lời. Trong trường hợp bạn đưa vào bản mẫu hộp thoại, thủ tục xử lý trả về nguyên mẫu BOOL (cũng lại vẫn có ngoại lệ).
    _ Với các điều khiển con có sẵn trong Windows, thì chính Windows đã cấp phát sẵn thủ tục xử lý, bạn có thể SubClassing thủ tục xử lý, đây cũng là ngoài tầm của bạn.
    Như vậy trong CreateDialogBox, mã của bạn muốn tạo ra cửa sổ con với xử lý riêng, nhưng bạn lại chưa đăng ký lớp riêng (hàm RegisterDialogClass là mồ côi và chưa từng được gọi).
    Giả sử bạn đưa RegisterDialogClass vào hàm CreateDialogBox trước khi gọi CreateWindowEx, mình bàn tiếp tới hàm RegisterDialogClass.

    Bạn đăng ký lớp "DialogClass" với thủ tục xử lý chung với cửa sổ chính. Đến đây chắc bạn có thể hình dung mức độ va chạm rồi chứ, hiền nhiên là nó không xử lý theo những gì ta mong muốn.
    Giả sử, bạn đã đăng ký với thủ tục xử lý riêng là "DialogProc", mình bàn tới DialogProc.

    Trong WM_COMMAND của DialogProc, bạn cho nó "bước qua" trong switch-case - Bạn suy nghĩ thử xem, cửa sổ con có cơ hội sống sót không khi 99% là nó được tiếp tục bằng WM_CLOSE ngay sát dưới WM_COMMAND.

    Nói nhiều quá sợ bạn "tẩu hỏa nhập ma". Trước mắt bạn đăng ký riêng một lớp với thủ tục xử lý riêng và chú ý phần hành chung lẫn cấu trúc chương trình như mình đã trình bày ở trên.
    Đi từ từ thôi bạn, anh em luôn đồng hành, sau này khi khá rồi đừng quên anh em là được, hì hì [IMG]images/smilies/17.gif[/IMG][IMG]images/smilies/17.gif[/IMG][IMG]images/smilies/17.gif[/IMG]
    anh em gì anh? chắc mỗi anh còn nhiệt tình trong diễn đàn này
    e ở HN. cũng hướng theo code virut nhưng trong tay bây h chỉ có: C, 1 chút kiến thức về PE file và đang luyện tập với Win32 api.
    A có lời khuyên nào ko ạ?
    à e sinh năm 96. [IMG]images/smilies/wave.gif[/IMG]

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Cái này có lẽ bạn phải xem lại cơ chế xử lý thông điệp trong chương trình Windows. Không phải ngẫu nhiên mình đề nghị bạn nên xem phần hành chung.

    Trong Windows, phần lớn thời gian chương trình bạn chẳng được ai (hoặc Windows) đoái hoài gì tới, mà nó chỉ nằm im chờ thời thôi. Khi có một sự kiện gì xảy ra, nếu liên quan tới chương trình của bạn thì Windows mới gọi hàm xử lý thông điệp (WndProc) mà bạn đã viết. Ví dụ như người dùng Click trên cửa sổ chương trình bạn, sau nhiều xử lý riêng, Windows mới gọi WndProc với ý nghĩa : "Đây, tao thương chú em mày ngồi chơi xơi nước nhiều quá, tụi người dùng nó Click trên cửa sổ của chú em mày đó, mày tính sao ?". Và Windows giải thích thêm : " Tao đưa cho chú em mày tọa độ mà tụi người dùng nó Click trong tham số lParam nè, hoành độ trong LOWORD(lParam) và tung độ trong HIWORD(lParam) và cả 2 là tính từ góc trái trên của cửa sổ chương trình chú em mày đó."

    Trên nghĩa đó, mình bàn tới thông điệp WM_COMMAND trong WndProc của bạn. Một điều chung nhất là khi xử lý WM_COMMAND bao giờ ta cũng phải xem nó bắt nguồn từ nơi đâu, cái nào ta xử lý thì nên trả về 0, cái nào không xử lý thì trả về DefWindowProc (vẫn có ngoại lệ), tức là ta phải xem các tình huống của lParam và wParam mà WndProc nhận (bạn đâu có muốn khi người dùng muốn nhập một xâu trong Edit nhưng chỉ vừa gõ một chữ thì nhảy ra cái hộp thoại đâu). Giả sử bạn đã qua được WM_COMMAND, mình bàn tiếp tới hàm CreateDialogBox của bạn.

    Bạn chưa phân biệt được đâu là cửa sổ con tự tạo; đâu là cửa sổ hộp thoại; đâu là cửa sổ điều khiển có sẵn.
    _ Khi bạn tạo cửa sổ con tự tạo thì bạn phải đăng ký một lớp cho nó, trong đó bao gồm cả thủ tục xử lý thông điệp riêng, thủ tục này trả về LRESULT.
    _ Khi bạn tạo môt hộp thoại thì bạn phải đưa vào bản mẫu hộp thoại và cái này bạn phải tạo tập tin tài nguyên và chứa bản mẫu trong đó. Trường hợp khác là bạn tự tạo ra bản mẫu mình không nói tới vì nó vượt quá sức của bạn, sau này bạn có thể hỏi tiếp mình sẽ trả lời. Trong trường hợp bạn đưa vào bản mẫu hộp thoại, thủ tục xử lý trả về nguyên mẫu BOOL (cũng lại vẫn có ngoại lệ).
    _ Với các điều khiển con có sẵn trong Windows, thì chính Windows đã cấp phát sẵn thủ tục xử lý, bạn có thể SubClassing thủ tục xử lý, đây cũng là ngoài tầm của bạn.
    Như vậy trong CreateDialogBox, mã của bạn muốn tạo ra cửa sổ con với xử lý riêng, nhưng bạn lại chưa đăng ký lớp riêng (hàm RegisterDialogClass là mồ côi và chưa từng được gọi).
    Giả sử bạn đưa RegisterDialogClass vào hàm CreateDialogBox trước khi gọi CreateWindowEx, mình bàn tiếp tới hàm RegisterDialogClass.

    Bạn đăng ký lớp "DialogClass" với thủ tục xử lý chung với cửa sổ chính. Đến đây chắc bạn có thể hình dung mức độ va chạm rồi chứ, hiền nhiên là nó không xử lý theo những gì ta mong muốn.
    Giả sử, bạn đã đăng ký với thủ tục xử lý riêng là "DialogProc", mình bàn tới DialogProc.

    Trong WM_COMMAND của DialogProc, bạn cho nó "bước qua" trong switch-case - Bạn suy nghĩ thử xem, cửa sổ con có cơ hội sống sót không khi 99% là nó được tiếp tục bằng WM_CLOSE ngay sát dưới WM_COMMAND.

    Nói nhiều quá sợ bạn "tẩu hỏa nhập ma". Trước mắt bạn đăng ký riêng một lớp với thủ tục xử lý riêng và chú ý phần hành chung lẫn cấu trúc chương trình như mình đã trình bày ở trên.
    Đi từ từ thôi bạn, anh em luôn đồng hành, sau này khi khá rồi đừng quên anh em là được, hì hì [IMG]images/smilies/17.gif[/IMG][IMG]images/smilies/17.gif[/IMG][IMG]images/smilies/17.gif[/IMG]

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •