Từ 1 tới 4 trên tổng số 4 kết quả

Đề tài: Hướng dẫn viết một chương trình chạy nền bằng VC++

  1. #1
    Ngày gia nhập
    07 2006
    Nơi ở
    Hanoi, Vietnam
    Bài viết
    2,750

    Post Hướng dẫn viết một chương trình chạy nền bằng VC++

    Hỏi: Xin hướng dẫn viết một chương trình chạy nền, khi nhấn tổ hợp phím thì chạy một đoạn code và nhấn tổ hợp phím khác thì dừng lại. Khi đang chạy một chương trình khác thì làm sao chương trình của tôi nhận được sự kiện nhấn tổ hợp phím?

    Đáp: Để ứng dụng có thể nhận và xử lý sự kiện I/O ở mọi tình huống (ngay cả khi ứng dụng khác đang chạy), bạn phải dùng kỹ thuật câu móc (Hooks) hàm xử lý sự kiện tương ứng vào Windows, hàm được câu móc cấp toàn hệ thống phải được đặt trong thư viện liên kết động *.dll. Như vậy ứng dụng xử lý phím nóng (hot-key) của bạn gồm 2 module:

    • file thư viện *.dll chứa hàm xử lý phím nóng và các hàm câu móc/gỡ ra.
    • file ứng dụng chứa các hàm chức năng mà sẽ được chạy/dừng khi tổ hợp phím tương ứng được ấn.
    Sau đây là qui trình cụ thể để xây dựng 2 module bằng ngôn ngữ VC++ của Microsoft.
    Để xây dựng thư viện KeyHook.dll chứa hàm chặn tổ hợp phím nóng mong muốn, bạn hãy tiến hành các bước sau đây:

    1. Chạy ứng dụng VC++ (phải cài đặt trước), chọn menu File.New.Projects, chọn loại Win32 Dynamic-link Library, chọn vị trí Location, nhập tên Project là KeyHook, ấn button Ok.
    2. Chọn checkbox A simple DLL project rồi chọn button Finish để tạo Project thực sự.
    3. Chọn menu File.New.Files, chọn loại C/C++ Header File, nhập tên KeyHook.h vào mục File name, ấn button Ok rồi viết đặc tả 2 hàm câu/gỡ hook như sau vào file KeyHook.h:

    Visual C++ Code:
    1. #include "stdafx.h"
    2. //hàm câu móc hàm xử lý phím vào Windows
    3. int FAR InstallHookKeyboard(HWND hWnd);
    4. //hàm gỡ hàm xử lý phím ra khỏi Windows
    5. int FAR UninstallHookKeyboard(void);

    4. Chọn menu File.New.Files, chọn loại Text File, nhập tên KeyHook.def vào mục File name, ấn button Ok rồi viết đặc tả thư viện *.dll như sau vào file
    Code:
    KeyHook.def:
    LIBRARY   KeyHook
    EXETYPE   WINDOWS
    CODE   PRELOAD MOVABLE
    DATA   PRELOAD SINGLE
    HEAPSIZE  8192
    STACKSIZE 8192
    EXPORTS
       InstallHookKeyboard @2
       UninstallHookKeyboard @3
    5. Chọn tab FileView ở dưới cửa sổ cây Project (thường nằm bên trái màn hình VC++), mở rộng nội dung của nhánh Source Files, nhấn đúp chuột vào file KeyHook.cpp để hiển thị nội dung của nó rồi hiệu chỉnh thành nội dung như sau:

    Visual C++ Code:
    1. //------------------------------
    2. // Nội dung file KeyHook.cpp
    3. //------------------------------
    4. #include "stdafx.h"
    5. #include "KeyHook.h"
    6. //định nghĩa các message cần dùng
    7. #define WM_MYSTART (WM_USER+1)
    8. #define WM_MYEND (WM_USER+2)
    9. //định nghĩa các biến cần dùng
    10. HWND hMyWnd;
    11. int fHookKeyboard;
    12. HANDLE hHookKeyboard;
    13. HINSTANCE hModuleDll;
    14. //------------------------------
    15. //Hàm khởi động của thư viện,
    16. //hàm này được kích hoạt tự động mỗi khi
    17. //thư viện được link với ứng dụng.
    18. //------------------------------
    19. BOOL APIENTRY DllMain(HINSTANCE hModule, ULONG ulReason, PCONTEXT pctx) {
    20.  switch (ulReason) {
    21.  case DLL_PROCESS_ATTACH:
    22.   if (hModuleDll==0)  hModuleDll= hModule;
    23.   break;
    24.  case DLL_PROCESS_DETACH:
    25.   UninstallHookKeyboard();
    26.   break;
    27.  } return TRUE;
    28. }
    29. //------------------------------
    30. // Hàm xử lý sự kiện phím
    31. //------------------------------
    32. LRESULT FAR PASCAL CALLBACK KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam) {
    33. short FAlt,FControl, FShift;
    34.    if (nCode >= 0 && nCode != HC_NOREMOVE && lParam >0) {
    35.  //xác định trạng thái các phím điều khiển
    36.       FShift = GetKeyState(VK_SHIFT);
    37.       FAlt = GetKeyState(VK_MENU);
    38.       FControl = GetKeyState(VK_CONTROL);
    39.       //kiểm tra tổ hợp phím Ctrl-S
    40.       if (FControl < 0 && wParam == 'S') {
    41.          //gởi thông báo WM_MYSTART về ứng dụng xử lý
    42.          SendMessage(hMyWnd, WM_MYSTART,wParam, (LPARAM)lParam);
    43.          return CallNextHookEx((struct HHOOK__ *)hHookKeyboard, nCode, wParam, lParam);
    44.       }
    45.       if (FControl < 0 && wParam == 'E') {
    46.          //gởi thông báo WM_MYEND về ứng dụng xử lý
    47.          SendMessage(hMyWnd, WM_MYEND,wParam, (LPARAM)lParam);
    48.          return CallNextHookEx((struct HHOOK__ *)hHookKeyboard, nCode, wParam, lParam);
    49.       }
    50.    }
    51.    return CallNextHookEx((struct HHOOK__ *)hHookKeyboard, nCode, wParam, lParam);
    52. }
    53. //------------------------------
    54. // Hàm câu móc hàm xử lý keyboard vào Windows
    55. //------------------------------
    56. int FAR InstallHookKeyboard(HWND hWnd) {
    57.    if (fHookKeyboard) return 1;
    58.    hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,
    59.       hModuleDll, 0);
    60.    if (hHookKeyboard == NULL) {
    61.       MessageBox(NULL,"Can't set Hook KeyboardProc","Error",MB_OK);
    62.       return 0;
    63.    }
    64.    hMyWnd = hWnd;
    65.    fHookKeyboard = 1;
    66.    return 1;
    67. }
    68. //------------------------------
    69. // Hàm gỡ hàm xử lý keyboard
    70. //------------------------------
    71. int FAR UninstallHookKeyboard(void) {
    72.    if (fHookKeyboard==0) return 0;
    73.    fHookKeyboard = 0;
    74.    return UnhookWindowsHookEx((struct HHOOK__ *)hHookKeyboard);
    75. }

    6. Chọn menu Build. Set Active Configuration, chọn mục Win32 Release, ấn button Ok.

    7. Chọn menu Build.Rebuild All để dịch Project thành file thư viện. Nếu bạn nhập đúng các nội dung trên thì quá trình dịch sẽ không có lỗi, trong Project sẽ có thư mục Release, trong thư mục này sẽ có nhiều file được tạo ra, trong đó bạn hãy quan sát 2 file tên là KeyHook.dll và KeyHook.lib, bạn sẽ copy 2 file này vào thư mục ứng dụng sẽ được viết trong giai đoạn 2 sau đây.

    Để xây dựng ứng dụng KeyHookDemo xử lý chức năng theo tổ hợp phím nóng, bạn hãy tiến hành các bước sau đây:

    1. Chạy ứng dụng VC++, chọn menu File.New.Projects, chọn loại Win32 Application, chọn vị trí Location, nhập tên Project là KeyHookDemo, ấn button Ok.

    2. Chọn checkbox A simple application rồi chọn button Finish để tạo Project thực sự.

    3. Copy 2 file đặc tả thư viện KeyHook.dll và KeyHook.lib vào thư mục ứng dụng (do Project hiện hành quản lý).

    4. Chọn menu File.New.Files, chọn loại C/C++ Source File, nhập tên KeyHookDemo.cpp vào mục File name, ấn button Ok rồi viết đoạn code xử lý sau vào file KeyHookDemo.cpp:

    Visual C++ Code:
    1. #include <windows.h>
    2. //khai báo các hàm trong thư viện KeyHook.dll
    3. int FAR InstallHookKeyboard(HWND hWnd);
    4. int FAR UninstallHookKeyboard(void);
    5. //khai báo các thông báo cần xử lý
    6. #define WM_MYSTART (WM_USER+1)
    7. #define WM_MYEND (WM_USER+2)
    8. //-----------------------------------
    9. //Hàm xử lý cửa sổ của ứng dụng
    10. //-----------------------------------
    11. long FAR PASCAL MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    12.    switch (message) {
    13.    case WM_CREATE:
    14.       //xảy ra 1 lần khi cửa sổ được tạo ra, câu móc hàm hook keyboard
    15.       if (InstallHookKeyboard(hWnd)==0)
    16.          MessageBox(NULL,"Khong cau moc ham xu ly keyboard duoc!!","Error",MB_OK);
    17.          break;
    18.    case WM_MYSTART:
    19.       //viết đoạn code thực hiện chức năng của bạn vào đây
    20.       SetWindowText(hWnd,"Bat dau thuc hien chuc nang cua ban");
    21.       break;
    22.    case WM_MYEND:
    23.       //viet doan code dieu khien dung chuc nang cua ban vao day
    24.       SetWindowText(hWnd,"Ket thuc thuc hien chuc nang cua ban");
    25.       break;
    26.    case WM_ENDSESSION:
    27.    case WM_CLOSE:
    28.    case WM_DESTROY:    
    29.       //xảy ra khi ứng dụng dừng
    30.       //gở bỏ hàm hook
    31.       UninstallHookKeyboard();
    32.       PostQuitMessage(0);
    33.       break;
    34.    default:
    35.       return (DefWindowProc(hWnd, message, wParam, lParam));
    36.    } // Switch message/
    37.    return ((long)NULL);
    38. }
    39. //-----------------------------------
    40. //Hàm khởi động ứng dụng
    41. //-----------------------------------
    42. int InitApplication(HINSTANCE hInstance)
    43. {
    44. WNDCLASS  wc;
    45.    wc.style = NULL; // Class style(s).
    46.    wc.lpfnWndProc = MainWndProc;
    47. // Function to retrieve messages
    48. //for windows of this class.
    49.    wc.cbClsExtra = 0;
    50.  // No per-class extra data.
    51.    wc.cbWndExtra = 0;
    52.   // No per-window extra data.
    53.    wc.hInstance = hInstance;
    54.  // Application that owns the class.
    55.    wc.hIcon = LoadIcon(hInstance, "ICON_1");
    56.    wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
    57.    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    58.    wc.lpszMenuName =  "KeyHookDemo";
    59. // Name of menu resource in .RC file.
    60.    wc.lpszClassName = "KeyHookDemo";
    61. // Name used in call to CreateWindow.
    62. // Register the window class
    63. //and return success/failure code.
    64.    return (RegisterClass(&wc));
    65. }
    66. //-----------------------------------
    67. //Hàm khởi động ứng dụng
    68. //-----------------------------------
    69. int InitInstance(HINSTANCE hInstance, short nCmdShow) {
    70. HWND hWnd;
    71.    nCmdShow = SW_MINIMIZE;
    72.    hWnd = CreateWindow(
    73.  "KeyHookDemo",
    74. // See RegisterClass() call.
    75.  "KeyHookDemo",
    76. // Text for window title bar.
    77.  WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX, // Window style.
    78.  50,30,400,150,
    79.  (HWND)NULL,
    80. // Overlapped windows have no parent.
    81.  (HMENU)NULL,
    82. // Use the window class menu.
    83.  hInstance,
    84. // This instance owns this window.
    85.  NULL);
    86. // Pointer not needed.
    87.    // If window could not be created, return "failure"
    88.    if (!hWnd) return (FALSE);
    89.    // Make the window visible; update its //client area; and return "success"
    90.    ShowWindow(hWnd, nCmdShow);
    91. // Show the window
    92.    return (TRUE);
    93. // Returns the value from PostQuitMessage
    94. }
    95. //-----------------------------------
    96. //Điểm nhập của ứng dụng
    97. //-----------------------------------
    98. int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    99. MSG msg;      // message
    100.    if (hPrevInstance)
    101.  // Other instances of app running?
    102.    return (FALSE);
    103.    if (!InitApplication(hInstance))
    104. // Initialize shared things
    105.    return (FALSE);
    106. // Exits if unable to initialize
    107.    if (!InitInstance(hInstance, nCmdShow))
    108.    return (FALSE);
    109.    //lặp chờ nhận và xử lý thông báo từ Windows
    110.    while (GetMessage(&msg,(HWND)NULL,(UINT)NULL,(UINT)NULL)) {
    111.  TranslateMessage(&msg);
    112.  // Translates virtual key codes
    113.  DispatchMessage(&msg);
    114.  // Dispatches message to window
    115.    }
    116.    return (msg.wParam);
    117.  // Returns the value from PostQuitMessage
    118. }
    5. Chọn menu Project.Settings, chọn tab Link, nhập thêm tên thư viện KeyHook.lib vào mục Object/Library module (lưu ý không xóa bất kỳ thư viện nào đã có trong mục này) rồi ấn button Ok.

    6. Chọn menu Build.Rebuild All để dịch Project thành file khả thi. Nếu bạn nhập đúng các nội dung trên thì quá trình dịch sẽ không có lỗi.

    7. Chọn menu Build.Execute KeyHookDemo để chạy thử ứng dụng, mỗi lần bạn ấn tổ hợp hot-key Ctrl-S và Ctrl-E, hàm hook sẽ phát hiện được và gửi thông báo tương ứng về ứng dụng. Đoạn code xử lý thông báo của ứng dụng sẽ xử lý các thông báo gửi về theo đúng yêu cầu của bạn.

    Lưu ý đoạn code của ứng dụng trên đây chỉ là khung sườn, bạn cần hiệu chỉnh lại đoạn code xử lý 2 thông báo WM_MYSTART và WM_MYEND theo yêu cầu riêng của mình.

    Bài được lấy từ PCWorld
    Email: admin[@]congdongcviet.com | CC to: info[@]congdongcviet.com
    Phone: 0972 89 7667 (Office: 04 6329 2380)
    Yahoo & Skype: dreaminess_world (Vui lòng chỉ rõ mục đích ngay khi liên hệ, cảm ơn!)

    Một người nào đó coi thường ý thức kỷ luật cũng có nghĩa là người đó đã coi thường tương lai số phận của chính bản thân người đó. Những người coi thường ý thức kỷ luật sẽ không bao giờ có được sự thành công trong sự nghiệp!

  2. #2
    Ngày gia nhập
    07 2006
    Nơi ở
    Hanoi, Vietnam
    Bài viết
    2,750

    Dr muốn biết nó có thực sự hay như các bạn nói không? Bây giờ Dr muốn xem sản phẩm của các bạn làm được từ đề tài này. Thế nào? Bạn thấy hay chắc là đã làm được rồi chứ? Đừng ngại, đưa lên cho Dr xem đi.
    Email: admin[@]congdongcviet.com | CC to: info[@]congdongcviet.com
    Phone: 0972 89 7667 (Office: 04 6329 2380)
    Yahoo & Skype: dreaminess_world (Vui lòng chỉ rõ mục đích ngay khi liên hệ, cảm ơn!)

    Một người nào đó coi thường ý thức kỷ luật cũng có nghĩa là người đó đã coi thường tương lai số phận của chính bản thân người đó. Những người coi thường ý thức kỷ luật sẽ không bao giờ có được sự thành công trong sự nghiệp!

  3. #3
    Ngày gia nhập
    12 2007
    Bài viết
    7

    Em viết theo chương trình này theo ví dụ nó ko hoạt động.
    1) Nếu ở chố hàm xử lý key trong file dll, nếu là show message box thì OK, nhưng nếu là ghi vào file, hoặc SendMessage cho cửa sổ chính thì ko hoạt động nếu cửa sổ chính ở minimze.
    2) Nếu dùng 1 biến static để ghi số lần nhấn Alt chằng hạng trong file dll, nó tăng 0,1,2.. sau mỗi lần gọi, nhưng nếu cửa sổ chính chuyển trạng thái normal <-> minimze thì biến này bị set lại. Như vậy có thể có 2 instance của file dll?
    Sau đây là code file dll:
    Visual C++ Code:
    1. // KeyHook.cpp : Defines the entry point for the DLL application.
    2. //
    3.  
    4. #include "stdafx.h"
    5. #include "KeyHook.h"
    6. #include "stdio.h"
    7. #include "fstream.h"
    8.  
    9.  
    10. #define WM_MYSTART (WM_USER+1)
    11. #define WM_MYEND (WM_USER+2)
    12.  
    13.  
    14. static HWND hMyWnd;
    15. static char count = '0';
    16. int fHookKeyBoard;
    17. HANDLE hHookKeyBoard;
    18. HINSTANCE hModuleDll;
    19. FILE * f1;
    20. char keylog[4096];
    21.  
    22. BOOL WINAPI DllMain(HANDLE hModule, DWORD ulReason, LPVOID pctx)
    23. {
    24.     switch(ulReason)
    25.     {
    26.     case DLL_PROCESS_ATTACH:
    27.         if(hModuleDll==0)
    28.             hModuleDll = (HINSTANCE)hModule;
    29.         break;
    30.     case DLL_PROCESS_DETACH:
    31.         UninstallHookKeyboard();
    32.         break;
    33.     }
    34.     return TRUE;
    35. }
    36.  
    37. void writeToFile(char ch)
    38. {
    39.     HANDLE hFile;
    40.     DWORD dNumWriten;
    41.     BOOL bTest;
    42.     DWORD dwBuffer[1];
    43.     dwBuffer[0] = ch;
    44.     DWORD dPos;
    45.    
    46.     hFile = CreateFile("keylog.txt", GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
    47.    
    48.     dPos = SetFilePointer(hFile,0,NULL,FILE_END);
    49.     bTest = WriteFile(hFile,dwBuffer,sizeof(DWORD), &dNumWriten,NULL);
    50.     bTest = CloseHandle(hFile);
    51. }
    52.  
    53. LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    54. {
    55.     short FAlt, FControl, FShift;
    56.     char ch;
    57.     if(nCode >= 0 && nCode != HC_NOREMOVE && lParam >0){
    58.         FShift = GetKeyState(VK_SHIFT);
    59.         FAlt = GetKeyState(VK_MENU);
    60.         FControl = GetKeyState(VK_CONTROL);
    61.        
    62.         // Start when user press Control
    63.        
    64.         if(FControl < 0)
    65.         {
    66.             SendMessage(hMyWnd, WM_MYSTART, wParam, (LPARAM)lParam);
    67.         }
    68.         else
    69.             if(FAlt < 0)
    70.             {
    71.                //save();
    72.                 char * msg = new char [1];
    73.                 msg[0] = (char)count++;
    74.                 MessageBox(NULL,msg,"Caption",MB_OK);
    75.  
    76.             }
    77.             else
    78.             {
    79.                 BYTE b[256];
    80.                 GetKeyboardState(b);
    81.                 WORD w;
    82.                 UINT scan = 0;
    83.                 ToAscii(wParam,scan,b,&w,0);
    84.                 ch = char(w);
    85.                 //f1 = fopen("keylog.txt","a+");
    86.                 char * msg = new char [256];
    87.                 msg[0] = ch;
    88.                 //fwrite(msg,sizeof(char),1,f1);
    89.                 //ofstream fout;
    90.                 //fout.open("keylog.txt");
    91.                 //fout<<msg;
    92.                 //fout << flush;
    93.                 //fout.close();
    94.                 strcat(keylog,msg);
    95.                 GetWindowText(hMyWnd,msg,256);
    96.                 MessageBox(NULL,msg,"Message Box",MB_OK);
    97.                 MessageBox(NULL,keylog,"Message Box",MB_OK);
    98.             }
    99.             return CallNextHookEx((struct HHOOK__ *) hHookKeyBoard,nCode, wParam,lParam);
    100.     }
    101.     return CallNextHookEx((struct HHOOK__ *) hHookKeyBoard,nCode, wParam,lParam);
    102. }
    103.  
    104. int FAR InstallHookKeyboard(HWND hWnd)
    105. {
    106.     if(fHookKeyBoard)
    107.         return 1;
    108.     hHookKeyBoard = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) KeyboardProc, hModuleDll, 0);
    109.     if(hHookKeyBoard == NULL)
    110.     {
    111.         // Error
    112.         MessageBox(NULL,"Can't set Hook KeyboardProc", "Error", MB_OK);
    113.         return 0;
    114.     }
    115.     hMyWnd = hWnd;
    116.     fHookKeyBoard = 1;
    117.     f1 = fopen("keylog.txt","w");
    118.     fclose(f1);
    119.     strcpy(keylog,"");
    120.     return 1;
    121. }
    122.  
    123. void save()
    124. {
    125.     ofstream fout;
    126.     fout.open("keylog.txt");
    127.     fout << keylog;
    128.     fout << flush;
    129.     fout.close();
    130.     MessageBox(NULL,keylog,"String",MB_OK);
    131. }
    132. int FAR UninstallHookKeyboard(void)
    133. {
    134.     if(fHookKeyBoard == 0)
    135.         return 0;
    136.     fHookKeyBoard = 0;
    137.     return UnhookWindowsHookEx((struct HHOOK__ *) hHookKeyBoard);
    138.    
    139. }
    140.  
    141. UINT saveThread(LPVOID param)
    142. {
    143.     save();
    144.     return 0;
    145. }

  4. #4
    Ngày gia nhập
    07 2007
    Nơi ở
    TP.HCM
    Bài viết
    199

    Mình nghĩ cách này cũng không hay lắm đâu, ví dụ trong CALLBACK KeyboardProc làm sao xác định được phím được ấn là phím nào, trạng thái down hay up. Code trên chỉ kiểm tra xem 1 phím chỉ định có được ấn hay không?

    Giải quyết bằng cách chặn phím cấp thấp, thay WH_KEYBOARD = WH_KEYBOARD_LL (constant này trong vc6 không có, các bạn phải xem google khai báo thêm, mình không nhớ nó là bao nhiêu), rồi sử lý theo MSDN thì rất OK.

    Theo yêu cầu bài trên thì chỉ cần bắt tổ hợp phím, vì thế không cần đao to búa lớn là phải cài đặt hook và viết dll này nọ đâu, chỉ cần dùng hàm RegisterHotKey để đăng ký phím tắt cho chương trình, rồi bắt sự kiện WM_HOTKEY trong long FAR PASCAL MainWndProc là được, đơn giản mà lại hiệu quả.

    Mình đã làm và thành công.

Các đề tài tương tự

  1. Trả lời: 8
    Bài viết cuối: 12-11-2013, 11:52 AM
  2. Viết ứng dụng kiểm tra tính chất của tam và tứ giác bằng C#
    Gửi bởi tvquang92 trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 0
    Bài viết cuối: 22-04-2013, 04:36 PM
  3. Hướng dẫn viết một chương trình C++ để chạy một chương trình khác.
    Gửi bởi mandemvotan trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 1
    Bài viết cuối: 26-08-2011, 09:10 PM
  4. Chú thích XML cho chương trình viết bằng C#
    Gửi bởi sunflower trong diễn đàn Tutorials và Thủ thuật lập trình C#, ASP.NET
    Trả lời: 6
    Bài viết cuối: 27-01-2011, 03:08 AM
  5. Hỏi: Viết C++ để chạy không cần .net
    Gửi bởi tuan1010 trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 1
    Bài viết cuối: 03-06-2010, 09:05 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn