Advertisement
alien_fx_fiend

Dictionary GUI-Based Now With Enter KeyPress Simulated !!! (*FINAL COMPLETE*)

Jul 31st, 2024 (edited)
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 35.23 KB | None | 0 0
  1. Hee's the full code for realtime-search.cpp file::
  2. #include <Windows.h>
  3. #include <CommCtrl.h>
  4. #include <fstream>
  5. #include <sstream>
  6. #include <string>
  7. #include <algorithm>
  8. #include <vector>
  9. #include "resource2.h"
  10.  
  11. #pragma comment(lib, "comctl32.lib")
  12.  
  13. using namespace std;
  14.  
  15. // Structure to represent a dictionary entry
  16. struct DictionaryEntry {
  17.    wstring word;
  18.    wstring definition;
  19. };
  20.  
  21. // Structure to represent a node in the linked list
  22. struct Node {
  23.    DictionaryEntry data;
  24.    Node* next;
  25. };
  26.  
  27. Node* dictionary = nullptr;
  28. vector<wstring> words;
  29. WNDPROC oldWordEditProc;
  30. WNDPROC oldDefinitionEditProc;
  31. HHOOK g_hHook = NULL;
  32. HWND g_hDlg = NULL;
  33.  
  34. // Function prototypes
  35. //LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  36. LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
  37. void AddWordToList(HWND hwnd);
  38. void insertNode(Node*& head, const DictionaryEntry& entry);
  39. //void addWord(Node*& head, const wstring& word, const wstring& definition);
  40. bool addWord(Node*& head, const wstring& word, const wstring& definition);
  41. void deleteWord(Node*& head, const wstring& keyword);
  42. wstring InputBox(HWND hwnd, const wstring& prompt, const wstring& title);
  43. void DisplayDefinition(HWND hwnd, const wstring& word, const wstring& definition);
  44. void editWord(Node* head, const wstring& oldWord, const wstring& newWord, const wstring& newDefinition);
  45. void listWords(const Node* head, vector<wstring>& words);
  46. void serializeDictionary(const Node* head, const wstring& filename);
  47. void deserializeDictionary(Node*& head, const wstring& filename);
  48. void searchWordRealtime(const Node* head, const wstring& keyword, vector<wstring>& suggestions);
  49. int pruneDictionary(Node*& head);
  50. void updateDictionaryAfterPrune(Node*& head, vector<wstring>& words, HWND hwnd);
  51. void updateListBox(HWND hwnd, const vector<wstring>& words);
  52.  
  53. // Function implementations
  54. void insertNode(Node*& head, const DictionaryEntry& entry) {
  55.    Node* newNode = new Node{ entry, nullptr };
  56.    if (!head) {
  57.        head = newNode;
  58.    }
  59.    else {
  60.        Node* current = head;
  61.        while (current->next) {
  62.            current = current->next;
  63.        }
  64.        current->next = newNode;
  65.    }
  66. }
  67.  
  68. bool addWord(Node*& head, const wstring& word, const wstring& definition) {
  69.    // Check if the word already exists
  70.    Node* current = head;
  71.    while (current) {
  72.        if (current->data.word == word) {
  73.            return false; // Word already exists, don't add
  74.         }
  75.         current = current->next;
  76.     }
  77.  
  78.     // Word doesn't exist, add it
  79.     insertNode(head, { word, definition });
  80.     return true;
  81. }
  82. // w/o duplicates
  83. /* // Modify the addWord function to check for duplicates
  84. bool addWord(Node*& head, const wstring& word, const wstring& definition) {
  85.     // Check if the word already exists
  86.     Node* current = head;
  87.     while (current) {
  88.         if (current->data.word == word) {
  89.             return false; // Word already exists, don't add
  90.         }
  91.         current = current->next;
  92.     }
  93.  
  94.     // Word doesn't exist, add it
  95.     insertNode(head, { word, definition });
  96.     return true;
  97. }*/
  98. // /w duplicates
  99. /*void addWord(Node*& head, const wstring& word, const wstring& definition) {
  100.     insertNode(head, { word, definition });
  101. }*/
  102.  
  103. void deleteWord(Node*& head, const wstring& keyword) {
  104.     if (!head) return;
  105.  
  106.     if (head->data.word == keyword) {
  107.         Node* temp = head;
  108.         head = head->next;
  109.         delete temp;
  110.         return;
  111.     }
  112.  
  113.     Node* current = head;
  114.     while (current->next && current->next->data.word != keyword) {
  115.         current = current->next;
  116.     }
  117.  
  118.     if (current->next) {
  119.         Node* temp = current->next;
  120.         current->next = current->next->next;
  121.         delete temp;
  122.     }
  123. }
  124.  
  125. // Modify the InputBox function to pre-populate the input
  126. wstring InputBox(HWND hwnd, const wstring& prompt, const wstring& title, const wstring& defaultValue = L"") {
  127.     wstring input = defaultValue;
  128.     DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_INPUT), hwnd,
  129.         [](HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -> INT_PTR {
  130.             static wstring* pInput;
  131.             switch (message) {
  132.             case WM_INITDIALOG:
  133.                 pInput = (wstring*)lParam;
  134.                 SetDlgItemText(hDlg, IDC_INPUT, pInput->c_str());
  135.                 SendDlgItemMessage(hDlg, IDC_INPUT, EM_SETSEL, 0, -1);  // Select all text
  136.                 return (INT_PTR)TRUE;
  137.             case WM_COMMAND:
  138.                 if (LOWORD(wParam) == IDOK) {
  139.                     HWND hEdit = GetDlgItem(hDlg, IDC_INPUT);
  140.                     int len = GetWindowTextLength(hEdit) + 1;
  141.                     wchar_t* buffer = new wchar_t[len];
  142.                     GetWindowText(hEdit, buffer, len);
  143.                     *pInput = buffer;
  144.                     delete[] buffer;
  145.                     EndDialog(hDlg, IDOK);
  146.                     return (INT_PTR)TRUE;
  147.                 }
  148.                 else if (LOWORD(wParam) == IDCANCEL) {
  149.                     EndDialog(hDlg, IDCANCEL);
  150.                     return (INT_PTR)TRUE;
  151.                 }
  152.                 break;
  153.             }
  154.             return (INT_PTR)FALSE;
  155.         }, (LPARAM)&input);
  156.     return input;
  157. }
  158. /*wstring InputBox(HWND hwnd, const wstring& prompt, const wstring& title) {
  159.     wchar_t input[156] = L"";
  160.     if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_INPUT), hwnd,
  161.         [](HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -> INT_PTR {
  162.             static wchar_t input[156];
  163.             switch (message) {
  164.             case WM_INITDIALOG: {
  165.                 HWND hEdit = GetDlgItem(hDlg, IDC_INPUT);
  166.                 SetWindowText(hEdit, (LPCWSTR)lParam);
  167.                 SendMessage(hEdit, EM_SETSEL, 0, -1); // Select all text
  168.                 break;
  169.             }
  170.             case WM_COMMAND:
  171.                 if (LOWORD(wParam) == IDOK) {
  172.                     GetDlgItemText(hDlg, IDC_INPUT, input, 156);
  173.                     EndDialog(hDlg, IDOK);
  174.                     return (INT_PTR)TRUE;
  175.                 }
  176.                 else if (LOWORD(wParam) == IDCANCEL) {
  177.                     EndDialog(hDlg, IDCANCEL);
  178.                     return (INT_PTR)TRUE;
  179.                 }
  180.                 break;
  181.             }
  182.             return (INT_PTR)FALSE;
  183.         }, (LPARAM)prompt.c_str()) == IDOK) {
  184.         return (wstring)input;
  185.     }
  186.     return L"";
  187. }*/
  188.  
  189. void DisplayDefinition(HWND hwnd, const wstring& word, const wstring& definition) {
  190.     wstring message = L"Definition of '" + word + L"':\n\n" + definition;
  191.     HWND hDlg = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DEFINITION), hwnd, [](HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -> INT_PTR {
  192.         switch (message) {
  193.         case WM_INITDIALOG:
  194.         {
  195.             wstring* definition = (wstring*)lParam;
  196.             SetDlgItemText(hDlg, IDC_DEFINITION_EDIT, definition->c_str());
  197.             delete definition;
  198.         }
  199.         return (INT_PTR)TRUE;
  200.         case WM_COMMAND:
  201.             if (LOWORD(wParam) == IDCANCEL) {
  202.                 EndDialog(hDlg, LOWORD(wParam));
  203.                 return (INT_PTR)TRUE;
  204.             }
  205.             break;
  206.         case WM_CLOSE:
  207.             EndDialog(hDlg, 0);
  208.             return (INT_PTR)TRUE;
  209.         }
  210.         return (INT_PTR)FALSE;
  211.         }, (LPARAM)new wstring(message));
  212.     ShowWindow(hDlg, SW_SHOW);
  213. }
  214. /*void DisplayDefinition(HWND hwnd, const wstring& word, const wstring& definition) {
  215.     wstring message = L"Definition of '" + word + L"':\n\n" + definition;
  216.     MessageBox(hwnd, message.c_str(), L"Word Definition", MB_OK | MB_ICONINFORMATION);
  217. }*/
  218.  
  219. void editWord(Node* head, const wstring& oldWord, const wstring& newWord, const wstring& newDefinition) {
  220.     Node* current = head;
  221.     while (current) {
  222.         if (current->data.word == oldWord) {
  223.             current->data.word = newWord;
  224.             current->data.definition = newDefinition;
  225.             return;
  226.         }
  227.         current = current->next;
  228.     }
  229. }
  230.  
  231. void listWords(const Node* head, vector<wstring>& words) {
  232.     words.clear();
  233.     const Node* current = head;
  234.     while (current) {
  235.         words.push_back(current->data.word);
  236.         current = current->next;
  237.     }
  238. }
  239.  
  240. // Delimiter Old Semicolon
  241. void serializeDictionary(const Node* head, const wstring& filename) {
  242.     wofstream file(filename, ios::out | ios::trunc);
  243.     if (!file.is_open()) {
  244.         MessageBox(NULL, L"Failed to open file for writing", L"Error", MB_OK | MB_ICONERROR);
  245.         return;
  246.     }
  247.     const Node* current = head;
  248.     while (current) {
  249.         file << current->data.word << L";" << current->data.definition << endl;
  250.         current = current->next;
  251.     }
  252.     file.close();
  253. }
  254.  
  255. // Delimiter Old Semicolon
  256. void deserializeDictionary(Node*& head, const wstring& filename) {
  257.     wifstream file(filename);
  258.     if (!file.is_open()) {
  259.         MessageBox(NULL, L"Failed to open dictionary file", L"Error", MB_OK | MB_ICONERROR);
  260.         return;
  261.     }
  262.     wstring line;
  263.     while (getline(file, line)) {
  264.         size_t pos = line.find(L';');
  265.         if (pos != wstring::npos) {
  266.             wstring word = line.substr(0, pos);
  267.             wstring definition = line.substr(pos + 1);
  268.             addWord(head, word, definition);
  269.         }
  270.     }
  271.     file.close();
  272. }
  273.  
  274. // Add this function to convert a string to lowercase
  275. wstring toLower(const wstring& str) {
  276.     wstring lower = str;
  277.     transform(lower.begin(), lower.end(), lower.begin(), ::towlower);
  278.     return lower;
  279. }
  280.  
  281. // Modify the searchWordRealtime function to be case-insensitive
  282. void searchWordRealtime(const Node* head, const wstring& keyword, vector<wstring>& suggestions) {
  283.     suggestions.clear();
  284.     const Node* current = head;
  285.     wstring lowercaseKeyword = toLower(keyword);
  286.     while (current) {
  287.         wstring lowercaseWord = toLower(current->data.word);
  288.         if (lowercaseWord.find(lowercaseKeyword) != wstring::npos) {
  289.             suggestions.push_back(current->data.word);
  290.         }
  291.         current = current->next;
  292.     }
  293. }
  294.  
  295. // Prune Functions
  296. int pruneDictionary(Node*& head) {
  297.     if (!head) return 0;
  298.  
  299.     int duplicatesRemoved = 0;
  300.     Node* current = head;
  301.  
  302.     while (current && current->next) {
  303.         Node* runner = current;
  304.         while (runner->next) {
  305.             if (current->data.word == runner->next->data.word) {
  306.                 Node* duplicate = runner->next;
  307.                 runner->next = runner->next->next;
  308.                 delete duplicate;
  309.                 duplicatesRemoved++;
  310.             }
  311.             else {
  312.                 runner = runner->next;
  313.             }
  314.         }
  315.         current = current->next;
  316.     }
  317.  
  318.     return duplicatesRemoved;
  319. }
  320.  
  321. // Prune Functions
  322. void updateDictionaryAfterPrune(Node*& head, vector<wstring>& words, HWND hwnd) {
  323.     listWords(head, words);
  324.     updateListBox(hwnd, words);
  325.     serializeDictionary(head, L"myDictionary99x.txt");
  326. }
  327.  
  328. void updateListBox(HWND hwnd, const vector<wstring>& words) {
  329.     HWND hListBox = GetDlgItem(hwnd, IDC_LISTBOX);
  330.     SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
  331.     for (const auto& word : words) {
  332.         SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)word.c_str());
  333.     }
  334. }
  335.  
  336. void AddWordToList(HWND hwnd) {
  337.     wchar_t word[256], definition[1024];
  338.     GetDlgItemText(hwnd, IDC_WORD_INPUT, word, 256);
  339.     GetDlgItemText(hwnd, IDC_DEFINITION_INPUT, definition, 1024);
  340.     if (wcslen(word) > 0) {
  341.         if (!addWord(dictionary, word, definition)) {
  342.             wstring message = L"An entry with the name '";
  343.             message += word;
  344.             message += L"' already exists. Do you want to add a duplicate entry?";
  345.             int result = MessageBox(hwnd, message.c_str(), L"Confirm Duplicate Entry", MB_YESNO | MB_ICONQUESTION);
  346.  
  347.             if (result == IDYES) {
  348.                 insertNode(dictionary, { word, definition });
  349.             }
  350.         }
  351.         listWords(dictionary, words);
  352.         updateListBox(hwnd, words);
  353.         serializeDictionary(dictionary, L"myDictionary99x.txt");
  354.         SetDlgItemText(hwnd, IDC_WORD_INPUT, L"");
  355.         SetDlgItemText(hwnd, IDC_DEFINITION_INPUT, L"");
  356.     }
  357. }
  358.  
  359. LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
  360.     if (nCode == HC_ACTION) {
  361.         KBDLLHOOKSTRUCT* pKbdStruct = (KBDLLHOOKSTRUCT*)lParam;
  362.         if (wParam == WM_KEYDOWN && pKbdStruct->vkCode == VK_RETURN) {
  363.             HWND hFocus = GetFocus();
  364.             if (hFocus == GetDlgItem(g_hDlg, IDC_WORD_INPUT) ||
  365.                 hFocus == GetDlgItem(g_hDlg, IDC_DEFINITION_INPUT)) {
  366.                 AddWordToList(g_hDlg);
  367.                 return 1;  // Prevent further processing of this key
  368.             }
  369.         }
  370.     }
  371.     return CallNextHookEx(g_hHook, nCode, wParam, lParam);
  372. }
  373.  
  374. /*LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  375. {
  376.     if (uMsg == WM_KEYDOWN && wParam == VK_RETURN)
  377.     {
  378.         HWND hwndParent = (HWND)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  379.         if (hwndParent)
  380.         {
  381.             HWND hwndAddButton = GetDlgItem(hwndParent, IDC_ADD_WORD);
  382.             if (hwndAddButton)
  383.             {
  384.                 SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(IDC_ADD_WORD, BN_CLICKED), (LPARAM)hwndAddButton);
  385.                 return 0;
  386.             }
  387.         }
  388.     }
  389.  
  390.     return CallWindowProc((WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA), hWnd, uMsg, wParam, lParam);
  391. }*/
  392.  
  393. /*LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam,
  394.     LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
  395. {
  396.     if (uMsg == WM_KEYDOWN && wParam == VK_RETURN) {
  397.         HWND hwndParent = (HWND)dwRefData;
  398.         SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(IDC_ADD_WORD, BN_CLICKED),
  399.             (LPARAM)GetDlgItem(hwndParent, IDC_ADD_WORD));
  400.         return 0;
  401.     }
  402.     return DefSubclassProc(hWnd, uMsg, wParam, lParam);
  403. }*/
  404. /*LRESULT CALLBACK WordEditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  405.     if (uMsg == WM_KEYDOWN && wParam == VK_RETURN) {
  406.         SendMessage(GetParent(hWnd), WM_COMMAND, MAKEWPARAM(IDC_ADD_WORD, BN_CLICKED), (LPARAM)GetDlgItem(GetParent(hWnd), IDC_ADD_WORD));
  407.         return 0;
  408.     }
  409.     return CallWindowProc(oldWordEditProc, hWnd, uMsg, wParam, lParam);
  410. }
  411.  
  412. LRESULT CALLBACK DefinitionEditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  413.     if (uMsg == WM_KEYDOWN && wParam == VK_RETURN) {
  414.         SendMessage(GetParent(hWnd), WM_COMMAND, MAKEWPARAM(IDC_ADD_WORD, BN_CLICKED), (LPARAM)GetDlgItem(GetParent(hWnd), IDC_ADD_WORD));
  415.         return 0;
  416.     }
  417.     return CallWindowProc(oldDefinitionEditProc, hWnd, uMsg, wParam, lParam);
  418. }*/
  419.  
  420. // Dialog procedure
  421. // Modify the DialogProc function
  422. INT_PTR CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  423.     static HWND hFocusedEdit = nullptr; // Define hFocusedEdit here
  424.     static HWND hWordEdit = nullptr;
  425.     static HWND hDefinitionEdit = nullptr;
  426.     switch (uMsg) {
  427.     case WM_INITDIALOG:
  428.     {
  429.         // Load dictionary
  430.         /*wchar_t path[MAX_PATH];
  431.         GetModuleFileName(NULL, path, MAX_PATH);
  432.         wstring exePath(path);
  433.         wstring dirPath = exePath.substr(0, exePath.find_last_of(L"\\/"));
  434.         wstring filePath = dirPath + L"\\myDictionary99x.txt";*/
  435.  
  436.         deserializeDictionary(dictionary, L"myDictionary99x.txt");
  437.         listWords(dictionary, words);
  438.         updateListBox(hwnd, words);
  439.         g_hDlg = hwnd;  // Store the dialog handle globally
  440.         g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
  441.         //hWordEdit = GetDlgItem(hwnd, IDC_WORD_INPUT);
  442.         //hDefinitionEdit = GetDlgItem(hwnd, IDC_DEFINITION_INPUT);
  443.  
  444.         // Set up subclassing
  445.         /*SetWindowLongPtr(hWordEdit, GWLP_USERDATA, (LONG_PTR)hwnd);
  446.         SetWindowLongPtr(hDefinitionEdit, GWLP_USERDATA, (LONG_PTR)hwnd);
  447.         SetWindowLongPtr(hWordEdit, GWLP_WNDPROC, (LONG_PTR)EditSubclassProc);
  448.         SetWindowLongPtr(hDefinitionEdit, GWLP_WNDPROC, (LONG_PTR)EditSubclassProc);*/
  449.         SetFocus(GetDlgItem(hwnd, IDC_SEARCH_INPUT));  // Set focus to search field
  450.         return TRUE;
  451.     }
  452.  
  453.     case WM_COMMAND:
  454.         // Start Double-Click View ListBox Definitions function block
  455.         switch (HIWORD(wParam)) {
  456.         case LBN_DBLCLK:
  457.             if (LOWORD(wParam) == IDC_LISTBOX) {
  458.                 int index = SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETCURSEL, 0, 0);
  459.                 if (index != LB_ERR) {
  460.                     wchar_t word[256];
  461.                     SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETTEXT, index, (LPARAM)word);
  462.  
  463.                     // Find the definition for the selected word
  464.                     Node* current = dictionary;
  465.                     while (current) {
  466.                         if (current->data.word == word) {
  467.                             DisplayDefinition(hwnd, word, current->data.definition);
  468.                             break;
  469.                         }
  470.                         current = current->next;
  471.                     }
  472.                 }
  473.                 return TRUE;
  474.             }
  475.             //break;
  476.         //}
  477.  
  478.         case EN_SETFOCUS:
  479.             if (LOWORD(wParam) == IDC_WORD_INPUT || LOWORD(wParam) == IDC_DEFINITION_INPUT) {
  480.                 hFocusedEdit = (HWND)lParam;
  481.             }
  482.             break;
  483.         }
  484.  
  485.         // End Double-Click View ListBox Definitions function block
  486.         // Handle other controls
  487.         switch (LOWORD(wParam)) {
  488.         case IDC_ADD_WORD: {
  489.             if (LOWORD(wParam) == IDC_ADD_WORD) {
  490.                 AddWordToList(hwnd);
  491.                 return TRUE;
  492.             }
  493.             else if ((LOWORD(wParam) == IDC_WORD_INPUT || LOWORD(wParam) == IDC_DEFINITION_INPUT) &&
  494.                 HIWORD(wParam) == EN_SETFOCUS) {
  495.                 SetTimer(hwnd, 1, 10, NULL);
  496.                 return TRUE;
  497.             }
  498.             else if ((LOWORD(wParam) == IDC_WORD_INPUT || LOWORD(wParam) == IDC_DEFINITION_INPUT) &&
  499.                 HIWORD(wParam) == EN_KILLFOCUS) {
  500.                 KillTimer(hwnd, 1);
  501.                 return TRUE;
  502.             }
  503.             break;
  504.         }
  505.                 /*wchar_t word[256], definition[1024];
  506.                 GetDlgItemText(hwnd, IDC_WORD_INPUT, word, 256);
  507.                 GetDlgItemText(hwnd, IDC_DEFINITION_INPUT, definition, 1024);
  508.                 if (wcslen(word) > 0) {
  509.                     if (!addWord(dictionary, word, definition)) {
  510.                         // Word already exists, show confirmation box
  511.                         wstring message = L"An entry with the name '";
  512.                         message += word;
  513.                         message += L"' already exists. Do you want to add a duplicate entry?";
  514.                         int result = MessageBox(hwnd, message.c_str(), L"Confirm Duplicate Entry", MB_YESNO | MB_ICONQUESTION);
  515.  
  516.                         if (result == IDYES) {
  517.                             // User confirmed, add the duplicate entry
  518.                             insertNode(dictionary, { word, definition });
  519.                             listWords(dictionary, words);
  520.                             updateListBox(hwnd, words);
  521.                             serializeDictionary(dictionary, L"myDictionary99x.txt");
  522.                             SetDlgItemText(hwnd, IDC_WORD_INPUT, L"");
  523.                             SetDlgItemText(hwnd, IDC_DEFINITION_INPUT, L"");
  524.                         }
  525.                         // If result is IDNO, do nothing (silently ignore)
  526.                     }
  527.                     else {
  528.                         // Word added successfully
  529.                         listWords(dictionary, words);
  530.                         updateListBox(hwnd, words);
  531.                         serializeDictionary(dictionary, L"myDictionary99x.txt");
  532.                         SetDlgItemText(hwnd, IDC_WORD_INPUT, L"");
  533.                         SetDlgItemText(hwnd, IDC_DEFINITION_INPUT, L"");
  534.                     }
  535.                 }
  536.                 return TRUE;
  537.             }
  538.         }*/
  539.                          // w/o duplicates
  540.                          /*case IDC_ADD_WORD: {
  541.                              wchar_t word[256], definition[1024];
  542.                              GetDlgItemText(hwnd, IDC_WORD_INPUT, word, 256);
  543.                              GetDlgItemText(hwnd, IDC_DEFINITION_INPUT, definition, 1024);
  544.                              if (wcslen(word) > 0) {
  545.                                  if (addWord(dictionary, word, definition)) {
  546.                                      listWords(dictionary, words);
  547.                                      updateListBox(hwnd, words);
  548.                                      serializeDictionary(dictionary, L"myDictionary99x.txt");
  549.                                      SetDlgItemText(hwnd, IDC_WORD_INPUT, L"");
  550.                                      SetDlgItemText(hwnd, IDC_DEFINITION_INPUT, L"");
  551.                                  }
  552.                                  // If addWord returns false, it means the word already exists.
  553.                                  // We silently ignore it as per the requirement.
  554.                              }
  555.                              return TRUE;
  556.                          }*/
  557.                          // /w duplicates        
  558.                          /*case IDC_ADD_WORD: {
  559.                              wchar_t word[256], definition[1024];
  560.                              GetDlgItemText(hwnd, IDC_WORD_INPUT, word, 256);
  561.                              GetDlgItemText(hwnd, IDC_DEFINITION_INPUT, definition, 1024);
  562.                              if (wcslen(word) > 0) {  // Only check if word is not empty
  563.                                  addWord(dictionary, word, definition);
  564.                                  listWords(dictionary, words);
  565.                                  updateListBox(hwnd, words);
  566.                                  serializeDictionary(dictionary, L"myDictionary99x.txt");
  567.                                  SetDlgItemText(hwnd, IDC_WORD_INPUT, L"");
  568.                                  SetDlgItemText(hwnd, IDC_DEFINITION_INPUT, L"");
  569.                              }
  570.                              return TRUE;
  571.                          }*/
  572.  
  573.         case IDC_DELETE_WORD: {
  574.             int index = SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETCURSEL, 0, 0);
  575.             if (index != LB_ERR) {
  576.                 wchar_t word[256];
  577.                 SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETTEXT, index, (LPARAM)word);
  578.  
  579.                 // Create the confirmation message
  580.                 wstring message = L"Are you sure you want to delete the word '";
  581.                 message += word;
  582.                 message += L"'?";
  583.  
  584.                 // Show the confirmation box
  585.                 int result = MessageBox(hwnd, message.c_str(), L"Confirm Deletion", MB_YESNO | MB_ICONQUESTION);
  586.  
  587.                 // If the user clicks "Yes", proceed with deletion
  588.                 if (result == IDYES) {
  589.                     deleteWord(dictionary, word);
  590.                     listWords(dictionary, words);
  591.                     updateListBox(hwnd, words);
  592.                     serializeDictionary(dictionary, L"myDictionary99x.txt");
  593.                 }
  594.             }
  595.             return TRUE;
  596.         }
  597.  
  598.         case IDC_EDIT_WORD: {
  599.             int index = SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETCURSEL, 0, 0);
  600.             if (index != LB_ERR) {
  601.                 wchar_t wordToEdit[256];
  602.                 SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETTEXT, index, (LPARAM)wordToEdit);
  603.                 Node* current = dictionary;
  604.                 while (current) {
  605.                     if (current->data.word == wordToEdit) {
  606.                         wstring newWord = InputBox(hwnd, L"Edit Word", L"Edit Word", current->data.word);
  607.                         if (!newWord.empty()) {
  608.                             wstring newDefinition = InputBox(hwnd, L"Edit Definition", L"Edit Definition", current->data.definition);
  609.                             // newDefinition can be empty now
  610.                             SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_DELETESTRING, index, 0); // Delete the old word
  611.                             editWord(dictionary, wordToEdit, newWord, newDefinition);
  612.                             listWords(dictionary, words);
  613.                             updateListBox(hwnd, words);
  614.                             // fix for C++ best practices "<" Signed/ Unsigned Mismatch
  615.                             for (size_t i = 0; i < words.size(); i++) {
  616.                                 //for (int i = 0; i < words.size(); i++) {
  617.                                 if (words[i] == newWord) {
  618.                                     SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_SETCURSEL, static_cast<WPARAM>(i), 0); // Select the edited word
  619.                                     // fix for C++ best practices "<" Signed Unsigned Mismatch
  620.                                     //SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_SETCURSEL, i, 0); // Select the edited word
  621.                                     break;
  622.                                 }
  623.                             }
  624.                             serializeDictionary(dictionary, L"myDictionary99x.txt");
  625.                         }
  626.                         break;
  627.                     }
  628.                     current = current->next;
  629.                 }
  630.                 if (!current) {
  631.                     MessageBox(hwnd, L"Word not found in the dictionary.", L"Error", MB_OK | MB_ICONERROR);
  632.                 }
  633.             }
  634.             return TRUE;
  635.         }
  636.                           // /w duplicates (does not affect duplicates tho only no check for blank definitions
  637.                           /*case IDC_EDIT_WORD: {
  638.                               int index = SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETCURSEL, 0, 0);
  639.                               if (index != LB_ERR) {
  640.                                   wchar_t wordToEdit[256];
  641.                                   SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETTEXT, index, (LPARAM)wordToEdit);
  642.                                   Node* current = dictionary;
  643.                                   while (current) {
  644.                                       if (current->data.word == wordToEdit) {
  645.                                           wstring newWord = InputBox(hwnd, L"Edit Word", L"Edit Word", current->data.word);
  646.                                           if (!newWord.empty()) {
  647.                                               wstring newDefinition = InputBox(hwnd, L"Edit Definition", L"Edit Definition", current->data.definition);
  648.                                               SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_DELETESTRING, index, 0); // Delete the old word
  649.                                               editWord(dictionary, wordToEdit, newWord, newDefinition);
  650.                                               listWords(dictionary, words);
  651.                                               updateListBox(hwnd, words);
  652.                                               for (int i = 0; i < words.size(); i++) {
  653.                                                   if (words[i] == newWord) {
  654.                                                       SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_SETCURSEL, i, 0); // Select the edited word
  655.                                                       break;
  656.                                                   }
  657.                                               }
  658.                                               serializeDictionary(dictionary, L"myDictionary99x.txt");
  659.                                           }
  660.                                           break;
  661.                                       }
  662.                                       current = current->next;
  663.                                   }
  664.                                   if (!current) {
  665.                                       MessageBox(hwnd, L"Word not found in the dictionary.", L"Error", MB_OK | MB_ICONERROR);
  666.                                   }
  667.                               }
  668.                               return TRUE;
  669.                           }*/
  670.  
  671.         case IDC_VIEW_DEFINITION: {
  672.             int index = SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETCURSEL, 0, 0);
  673.             if (index != LB_ERR) {
  674.                 wchar_t word[256];
  675.                 SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETTEXT, index, (LPARAM)word);
  676.                 Node* current = dictionary;
  677.                 while (current) {
  678.                     if (current->data.word == word) {
  679.                         DisplayDefinition(hwnd, current->data.word, current->data.definition);
  680.                         break;
  681.                     }
  682.                     current = current->next;
  683.                 }
  684.             }
  685.             return TRUE;
  686.         }
  687.  
  688.         case IDC_SEARCH_INPUT: {
  689.             if (HIWORD(wParam) == EN_CHANGE) {
  690.                 wchar_t query[256];
  691.                 GetDlgItemText(hwnd, IDC_SEARCH_INPUT, query, 256);
  692.                 if (wcslen(query) == 0) {
  693.                     updateListBox(hwnd, words);
  694.                 }
  695.                 else {
  696.                     vector<wstring> suggestions;
  697.                     searchWordRealtime(dictionary, query, suggestions);
  698.                     updateListBox(hwnd, suggestions);
  699.                 }
  700.             }
  701.             return TRUE;
  702.         }
  703.  
  704.         case IDC_CLEAR_SEARCH: {
  705.             SetDlgItemText(hwnd, IDC_SEARCH_INPUT, L"");
  706.             updateListBox(hwnd, words);
  707.             return TRUE;
  708.         }
  709.  
  710.                              //Prune Functions
  711.         case IDC_PRUNE: {
  712.             int result = MessageBox(hwnd, L"Are you sure you want to prune the list and remove duplicates?", L"Confirm Prune", MB_YESNO | MB_ICONQUESTION);
  713.             if (result == IDYES) {
  714.                 int duplicatesRemoved = pruneDictionary(dictionary);
  715.                 updateDictionaryAfterPrune(dictionary, words, hwnd);
  716.  
  717.                 wstring message = L"Pruning complete. ";
  718.                 message += to_wstring(duplicatesRemoved);
  719.                 message += L" duplicate entries were removed.";
  720.                 MessageBox(hwnd, message.c_str(), L"Prune Results", MB_OK | MB_ICONINFORMATION);
  721.             }
  722.             return TRUE;
  723.         }
  724.  
  725.         case WM_TIMER:
  726.             if (wParam == 1) {
  727.                 if (GetAsyncKeyState(VK_RETURN) & 0x8000) {
  728.                     AddWordToList(hwnd);
  729.                     KillTimer(hwnd, 1);
  730.                     SetTimer(hwnd, 1, 10, NULL);  // Restart the timer
  731.                 }
  732.             }
  733.             break;
  734.         /*case IDC_WORD_INPUT:
  735.         case IDC_DEFINITION_INPUT:
  736.             if (HIWORD(wParam) == EN_SETFOCUS) {
  737.                 hFocusedEdit = (HWND)lParam;
  738.             }
  739.             break;
  740.             //}
  741.             //break;
  742.  
  743.                 case WM_KEYDOWN:
  744.             if (wParam == VK_RETURN) {
  745.                 HWND focusedControl = GetFocus();
  746.                 if (focusedControl == hWordEdit || focusedControl == hDefinitionEdit) {
  747.                     SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_ADD_WORD, BN_CLICKED), 0);
  748.                     return TRUE;
  749.                 }
  750.             }
  751.             break;*/
  752.  
  753.         case IDCANCEL:
  754.             DestroyWindow(hwnd);
  755.             PostQuitMessage(0);
  756.             return TRUE;
  757.         }
  758.         break;
  759.  
  760.     case WM_CLOSE:
  761.         if (g_hHook) {
  762.             UnhookWindowsHookEx(g_hHook);
  763.         }
  764.         DestroyWindow(hwnd);
  765.         PostQuitMessage(0);
  766.         return TRUE;
  767.     }
  768.    
  769.     return FALSE;
  770. }
  771.  
  772. int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
  773.     HWND hDlg = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_MAINDIALOG), 0, DialogProc, 0);
  774.     if (!hDlg) {
  775.         MessageBox(NULL, L"Failed to create dialog", L"Error", MB_ICONERROR | MB_OK);
  776.         return 1;
  777.     }
  778.  
  779.     ShowWindow(hDlg, nCmdShow);
  780.  
  781.     MSG msg;
  782.     BOOL bRet;
  783.     while ((bRet = GetMessage(&msg, nullptr, 0, 0)) != 0) {
  784.         if (bRet == -1) {
  785.             // Handle the error and possibly exit
  786.             break;
  787.         }
  788.         else if (!IsWindow(hDlg) || !IsDialogMessage(hDlg, &msg)) {
  789.             TranslateMessage(&msg);
  790.             DispatchMessage(&msg);
  791.         }
  792.     }
  793.  
  794.     return (int)msg.wParam;
  795. }
  796. Hee's the full code for Resource2.rc file::
  797. #include <windows.h>
  798. #include "resource2.h"
  799.  
  800. IDD_MAINDIALOG DIALOGEX 0, 0, 320, 240
  801. STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
  802. CAPTION "Dictionary Application"
  803. FONT 8, "MS Shell Dlg", 400, 0, 0x1
  804. BEGIN
  805. LTEXT           "Word:", -1, 10, 10, 30, 8
  806. EDITTEXT        IDC_WORD_INPUT, 50, 8, 100, 14, ES_AUTOHSCROLL | WS_TABSTOP
  807. LTEXT           "Definition:", -1, 10, 30, 40, 8
  808. EDITTEXT        IDC_DEFINITION_INPUT, 50, 28, 200, 14, ES_AUTOHSCROLL | WS_TABSTOP
  809. PUSHBUTTON      "Add Word", IDC_ADD_WORD, 260, 8, 50, 14
  810. PUSHBUTTON      "Delete Word", IDC_DELETE_WORD, 260, 28, 50, 14
  811. PUSHBUTTON      "Edit Word", IDC_EDIT_WORD, 260, 48, 50, 14
  812. PUSHBUTTON      "View Definition", IDC_VIEW_DEFINITION, 205, 8, 55, 14
  813. PUSHBUTTON      "Prune", IDC_PRUNE, 160, 8, 25, 14
  814. PUSHBUTTON      "Clear", IDC_CLEAR_SEARCH, 185, 8, 20, 14
  815. LTEXT           "Search:", -1, 10, 50, 30, 8
  816. EDITTEXT        IDC_SEARCH_INPUT, 50, 48, 200, 14, ES_AUTOHSCROLL
  817. LISTBOX         IDC_LISTBOX, 10, 70, 300, 160, LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL
  818. END
  819.  
  820. IDD_INPUT DIALOGEX 0, 0, 250, 120
  821. STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
  822. CAPTION "Input"
  823. FONT 8, "MS Shell Dlg", 400, 0, 0x1
  824. BEGIN
  825. LTEXT           "Input:", -1, 7, 14, 50, 8
  826. EDITTEXT        IDC_INPUT, 7, 30, 230, 20, ES_AUTOHSCROLL
  827. DEFPUSHBUTTON   "OK", IDOK, 70, 60, 50, 14
  828. PUSHBUTTON      "Cancel", IDCANCEL, 130, 60, 50, 14
  829. END
  830.  
  831. IDD_DEFINITION DIALOGEX 0, 0, 300, 200
  832. STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
  833. CAPTION "Definition"
  834. FONT 8, "MS Shell Dlg"
  835. BEGIN
  836. EDITTEXT        IDC_DEFINITION_EDIT, 7, 7, 286, 186, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL
  837. END
  838.  
  839. /*IDD_INPUT DIALOGEX 0, 0, 200, 100
  840. STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
  841. CAPTION "Input"
  842. FONT 8, "MS Shell Dlg"
  843. BEGIN
  844. LTEXT           "Input:", -1, 7, 14, 50, 8
  845. EDITTEXT        IDC_INPUT, 7, 24, 186, 12, ES_AUTOHSCROLL
  846. DEFPUSHBUTTON   "OK", IDOK, 139, 7, 50, 14
  847. PUSHBUTTON      "Cancel", IDCANCEL, 139, 24, 50, 14
  848. END*/
  849.  
  850. //EDITTEXT        IDC_WORD_INPUT, 50, 8, 100, 14, ES_AUTOHSCROLL
  851. //PUSHBUTTON      "Add Word", IDC_ADD_WORD, 260, 8, 50, 14
  852. //PUSHBUTTON      "View Definition", IDC_VIEW_DEFINITION, 260, 68, 50, 14
  853. Hee's the full code for resource2.h file::
  854. #ifndef RESOURCE2_H
  855. #define RESOURCE2_H
  856.  
  857. #define IDD_MAINDIALOG                  101
  858. #define IDC_WORD_INPUT                  1001
  859. #define IDC_DEFINITION_INPUT            1002
  860. #define IDC_ADD_WORD                    1003
  861. #define IDC_DELETE_WORD                 1004
  862. #define IDC_SEARCH_INPUT                1005
  863. #define IDC_LISTBOX                     1006
  864. #define IDC_INPUT                       1007  // Add this line if you're using IDC_INPUT
  865. #define IDC_EDIT_WORD                   1008
  866. #define IDC_VIEW_DEFINITION             1009
  867. #define IDD_INPUT                       1010
  868. #define IDD_DEFINITION                  1011
  869. #define IDC_DEFINITION_EDIT             1012
  870. #define IDC_CLEAR_SEARCH                1013
  871. #define IDC_PRUNE                       1014
  872.  
  873. #endif // RESOURCE2_H
  874.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement