Advertisement
alien_fx_fiend

Dictionary GUI-Based Win32 (Multiline Definition + Edit Word + Search Improved /w Clear + DelConfir)

Jul 29th, 2024 (edited)
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.68 KB | None | 0 0
  1. realtime-search.cpp::
  2. #include <Windows.h>
  3. #include <fstream>
  4. #include <sstream>
  5. #include <string>
  6. #include <algorithm>
  7. #include <vector>
  8. #include "resource2.h"
  9.  
  10. using namespace std;
  11.  
  12. // Structure to represent a dictionary entry
  13. struct DictionaryEntry {
  14.     wstring word;
  15.     wstring definition;
  16. };
  17.  
  18. // Structure to represent a node in the linked list
  19. struct Node {
  20.     DictionaryEntry data;
  21.     Node* next;
  22. };
  23.  
  24. Node* dictionary = nullptr;
  25. vector<wstring> words;
  26.  
  27. // Function prototypes
  28. void insertNode(Node*& head, const DictionaryEntry& entry);
  29. void addWord(Node*& head, const wstring& word, const wstring& definition);
  30. void deleteWord(Node*& head, const wstring& keyword);
  31. wstring InputBox(HWND hwnd, const wstring& prompt, const wstring& title);
  32. void DisplayDefinition(HWND hwnd, const wstring& word, const wstring& definition);
  33. void editWord(Node* head, const wstring& oldWord, const wstring& newWord, const wstring& newDefinition);
  34. void listWords(const Node* head, vector<wstring>& words);
  35. void serializeDictionary(const Node* head, const wstring& filename);
  36. void deserializeDictionary(Node*& head, const wstring& filename);
  37. void searchWordRealtime(const Node* head, const wstring& keyword, vector<wstring>& suggestions);
  38. void updateListBox(HWND hwnd, const vector<wstring>& words);
  39.  
  40. // Function implementations
  41. void insertNode(Node*& head, const DictionaryEntry& entry) {
  42.     Node* newNode = new Node{ entry, nullptr };
  43.     if (!head) {
  44.         head = newNode;
  45.     }
  46.     else {
  47.         Node* current = head;
  48.         while (current->next) {
  49.             current = current->next;
  50.         }
  51.         current->next = newNode;
  52.     }
  53. }
  54.  
  55. void addWord(Node*& head, const wstring& word, const wstring& definition) {
  56.     insertNode(head, { word, definition });
  57. }
  58.  
  59. void deleteWord(Node*& head, const wstring& keyword) {
  60.     if (!head) return;
  61.  
  62.     if (head->data.word == keyword) {
  63.         Node* temp = head;
  64.         head = head->next;
  65.         delete temp;
  66.         return;
  67.     }
  68.  
  69.     Node* current = head;
  70.     while (current->next && current->next->data.word != keyword) {
  71.         current = current->next;
  72.     }
  73.  
  74.     if (current->next) {
  75.         Node* temp = current->next;
  76.         current->next = current->next->next;
  77.         delete temp;
  78.     }
  79. }
  80.  
  81. wstring InputBox(HWND hwnd, const wstring& prompt, const wstring& title) {
  82.     wstring input;
  83.     DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_INPUT), hwnd,
  84.         [](HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -> INT_PTR {
  85.             static wstring* pInput;
  86.             switch (message) {
  87.             case WM_INITDIALOG:
  88.                 pInput = (wstring*)lParam;
  89.                 SetDlgItemText(hDlg, IDC_INPUT, pInput->c_str());
  90.                 return (INT_PTR)TRUE;
  91.             case WM_COMMAND:
  92.                 if (LOWORD(wParam) == IDOK) {
  93.                     HWND hEdit = GetDlgItem(hDlg, IDC_INPUT);
  94.                     int len = GetWindowTextLength(hEdit) + 1;
  95.                     wchar_t* buffer = new wchar_t[len];
  96.                     GetWindowText(hEdit, buffer, len);
  97.                     *pInput = buffer;
  98.                     delete[] buffer;
  99.                     EndDialog(hDlg, IDOK);
  100.                     return (INT_PTR)TRUE;
  101.                 }
  102.                 else if (LOWORD(wParam) == IDCANCEL) {
  103.                     EndDialog(hDlg, IDCANCEL);
  104.                     return (INT_PTR)TRUE;
  105.                 }
  106.                 break;
  107.             }
  108.             return (INT_PTR)FALSE;
  109.         }, (LPARAM)&input);
  110.     return input;
  111. }
  112.  
  113. void DisplayDefinition(HWND hwnd, const wstring& word, const wstring& definition) {
  114.     wstring message = L"Definition of '" + word + L"':\n\n" + definition;
  115.     HWND hDlg = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DEFINITION), hwnd, [](HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -> INT_PTR {
  116.         switch (message) {
  117.         case WM_INITDIALOG:
  118.         {
  119.             wstring* definition = (wstring*)lParam;
  120.             SetDlgItemText(hDlg, IDC_DEFINITION_EDIT, definition->c_str());
  121.             delete definition;
  122.         }
  123.         return (INT_PTR)TRUE;
  124.         case WM_COMMAND:
  125.             if (LOWORD(wParam) == IDCANCEL) {
  126.                 EndDialog(hDlg, LOWORD(wParam));
  127.                 return (INT_PTR)TRUE;
  128.             }
  129.             break;
  130.         case WM_CLOSE:
  131.             EndDialog(hDlg, 0);
  132.             return (INT_PTR)TRUE;
  133.         }
  134.         return (INT_PTR)FALSE;
  135.         }, (LPARAM)new wstring(message));
  136.     ShowWindow(hDlg, SW_SHOW);
  137. }
  138.  
  139. void editWord(Node* head, const wstring& oldWord, const wstring& newWord, const wstring& newDefinition) {
  140.     Node* current = head;
  141.     while (current) {
  142.         if (current->data.word == oldWord) {
  143.             current->data.word = newWord;
  144.             current->data.definition = newDefinition;
  145.             return;
  146.         }
  147.         current = current->next;
  148.     }
  149. }
  150.  
  151. void listWords(const Node* head, vector<wstring>& words) {
  152.     words.clear();
  153.     const Node* current = head;
  154.     while (current) {
  155.         words.push_back(current->data.word);
  156.         current = current->next;
  157.     }
  158. }
  159.  
  160. void serializeDictionary(const Node* head, const wstring& filename) {
  161.     wofstream file(filename);
  162.     const Node* current = head;
  163.     while (current) {
  164.         file << current->data.word << L";" << current->data.definition << endl;
  165.         current = current->next;
  166.     }
  167.     file.close();
  168. }
  169.  
  170. void deserializeDictionary(Node*& head, const wstring& filename) {
  171.     wifstream file(filename);
  172.     wstring line;
  173.     while (getline(file, line)) {
  174.         size_t pos = line.find(L';');
  175.         if (pos != wstring::npos) {
  176.             wstring word = line.substr(0, pos);
  177.             wstring definition = line.substr(pos + 1);
  178.             addWord(head, word, definition);
  179.         }
  180.     }
  181.     file.close();
  182. }
  183.  
  184. // Add this function to convert a string to lowercase
  185. wstring toLower(const wstring& str) {
  186.     wstring lower = str;
  187.     transform(lower.begin(), lower.end(), lower.begin(), ::towlower);
  188.     return lower;
  189. }
  190.  
  191. // Modify the searchWordRealtime function to be case-insensitive
  192. void searchWordRealtime(const Node* head, const wstring& keyword, vector<wstring>& suggestions) {
  193.     suggestions.clear();
  194.     const Node* current = head;
  195.     wstring lowercaseKeyword = toLower(keyword);
  196.     while (current) {
  197.         wstring lowercaseWord = toLower(current->data.word);
  198.         if (lowercaseWord.find(lowercaseKeyword) != wstring::npos) {
  199.             suggestions.push_back(current->data.word);
  200.         }
  201.         current = current->next;
  202.     }
  203. }
  204.  
  205. void updateListBox(HWND hwnd, const vector<wstring>& words) {
  206.     HWND hListBox = GetDlgItem(hwnd, IDC_LISTBOX);
  207.     SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
  208.     for (const auto& word : words) {
  209.         SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)word.c_str());
  210.     }
  211. }
  212.  
  213. // Dialog procedure
  214. // Modify the DialogProc function
  215. INT_PTR CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  216.     switch (uMsg) {
  217.     case WM_INITDIALOG:
  218.         deserializeDictionary(dictionary, L"dictionary.txt");
  219.         listWords(dictionary, words);
  220.         updateListBox(hwnd, words);
  221.         return TRUE;
  222.  
  223.     case WM_COMMAND:
  224.         switch (LOWORD(wParam)) {
  225.         case IDC_ADD_WORD: {
  226.             wchar_t word[256], definition[1024];
  227.             GetDlgItemText(hwnd, IDC_WORD_INPUT, word, 256);
  228.             GetDlgItemText(hwnd, IDC_DEFINITION_INPUT, definition, 1024);
  229.             if (wcslen(word) > 0 && wcslen(definition) > 0) {
  230.                 addWord(dictionary, word, definition);
  231.                 listWords(dictionary, words);
  232.                 updateListBox(hwnd, words);
  233.                 serializeDictionary(dictionary, L"dictionary.txt");
  234.                 SetDlgItemText(hwnd, IDC_WORD_INPUT, L"");
  235.                 SetDlgItemText(hwnd, IDC_DEFINITION_INPUT, L"");
  236.             }
  237.             return TRUE;
  238.         }
  239.  
  240.         case IDC_DELETE_WORD: {
  241.             int index = SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETCURSEL, 0, 0);
  242.             if (index != LB_ERR) {
  243.                 wchar_t word[256];
  244.                 SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETTEXT, index, (LPARAM)word);
  245.  
  246.                 // Create the confirmation message
  247.                 wstring message = L"Are you sure you want to delete the word '";
  248.                 message += word;
  249.                 message += L"'?";
  250.  
  251.                 // Show the confirmation box
  252.                 int result = MessageBox(hwnd, message.c_str(), L"Confirm Deletion", MB_YESNO | MB_ICONQUESTION);
  253.  
  254.                 // If the user clicks "Yes", proceed with deletion
  255.                 if (result == IDYES) {
  256.                     deleteWord(dictionary, word);
  257.                     listWords(dictionary, words);
  258.                     updateListBox(hwnd, words);
  259.                     serializeDictionary(dictionary, L"dictionary.txt");
  260.                 }
  261.             }
  262.             return TRUE;
  263.         }
  264.  
  265.         case IDC_EDIT_WORD: {
  266.             int index = SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETCURSEL, 0, 0);
  267.             if (index != LB_ERR) {
  268.                 wchar_t wordToEdit[256];
  269.                 SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETTEXT, index, (LPARAM)wordToEdit);
  270.                 wstring newWord = InputBox(hwnd, wordToEdit, L"Edit Word");
  271.                 if (!newWord.empty()) {
  272.                     Node* current = dictionary;
  273.                     while (current) {
  274.                         if (current->data.word == wordToEdit) {
  275.                             wstring newDefinition = InputBox(hwnd, current->data.definition.c_str(), L"Edit Definition");
  276.                             if (!newDefinition.empty()) {
  277.                                 SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_DELETESTRING, index, 0); // Delete the old word
  278.                                 editWord(dictionary, wordToEdit, newWord, newDefinition);
  279.                                 listWords(dictionary, words);
  280.                                 updateListBox(hwnd, words);
  281.                                 for (int i = 0; i < words.size(); i++) {
  282.                                     if (words[i] == newWord) {
  283.                                         SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_SETCURSEL, i, 0); // Select the edited word
  284.                                         break;
  285.                                     }
  286.                                 }
  287.                                 serializeDictionary(dictionary, L"dictionary.txt");
  288.                             }
  289.                             break;
  290.                         }
  291.                         current = current->next;
  292.                     }
  293.                     if (!current) {
  294.                         MessageBox(hwnd, L"Word not found in the dictionary.", L"Error", MB_OK | MB_ICONERROR);
  295.                     }
  296.                 }
  297.             }
  298.             return TRUE;
  299.         }
  300.  
  301.         case IDC_VIEW_DEFINITION: {
  302.             int index = SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETCURSEL, 0, 0);
  303.             if (index != LB_ERR) {
  304.                 wchar_t word[256];
  305.                 SendDlgItemMessage(hwnd, IDC_LISTBOX, LB_GETTEXT, index, (LPARAM)word);
  306.                 Node* current = dictionary;
  307.                 while (current) {
  308.                     if (current->data.word == word) {
  309.                         DisplayDefinition(hwnd, current->data.word, current->data.definition);
  310.                         break;
  311.                     }
  312.                     current = current->next;
  313.                 }
  314.             }
  315.             return TRUE;
  316.         }
  317.  
  318.         case IDC_SEARCH_INPUT: {
  319.             if (HIWORD(wParam) == EN_CHANGE) {
  320.                 wchar_t query[256];
  321.                 GetDlgItemText(hwnd, IDC_SEARCH_INPUT, query, 256);
  322.                 if (wcslen(query) == 0) {
  323.                     updateListBox(hwnd, words);
  324.                 }
  325.                 else {
  326.                     vector<wstring> suggestions;
  327.                     searchWordRealtime(dictionary, query, suggestions);
  328.                     updateListBox(hwnd, suggestions);
  329.                 }
  330.             }
  331.             return TRUE;
  332.         }
  333.  
  334.         case IDC_CLEAR_SEARCH: {
  335.             SetDlgItemText(hwnd, IDC_SEARCH_INPUT, L"");
  336.             updateListBox(hwnd, words);
  337.             return TRUE;
  338.         }
  339.  
  340.         case IDCANCEL:
  341.             DestroyWindow(hwnd);
  342.             PostQuitMessage(0);
  343.             return TRUE;
  344.         }
  345.         break;
  346.  
  347.     case WM_CLOSE:
  348.         DestroyWindow(hwnd);
  349.         PostQuitMessage(0);
  350.         return TRUE;
  351.     }
  352.     return FALSE;
  353. }
  354.  
  355. int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
  356.     HWND hDlg = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_MAINDIALOG), 0, DialogProc, 0);
  357.     if (!hDlg) {
  358.         MessageBox(NULL, L"Failed to create dialog", L"Error", MB_ICONERROR | MB_OK);
  359.         return 1;
  360.     }
  361.  
  362.     ShowWindow(hDlg, nCmdShow);
  363.  
  364.     MSG msg;
  365.     BOOL bRet;
  366.     while ((bRet = GetMessage(&msg, nullptr, 0, 0)) != 0) {
  367.         if (bRet == -1) {
  368.             // Handle the error and possibly exit
  369.             break;
  370.         }
  371.         else if (!IsWindow(hDlg) || !IsDialogMessage(hDlg, &msg)) {
  372.             TranslateMessage(&msg);
  373.             DispatchMessage(&msg);
  374.         }
  375.     }
  376.  
  377.     return (int)msg.wParam;
  378. }
  379.  
  380. Resource2.rc::
  381. #include <windows.h>
  382. #include "resource2.h"
  383.  
  384. IDD_MAINDIALOG DIALOGEX 0, 0, 320, 240
  385. STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
  386. CAPTION "Dictionary Application"
  387. FONT 8, "MS Shell Dlg", 400, 0, 0x1
  388. BEGIN
  389. LTEXT           "Word:", -1, 10, 10, 30, 8
  390. EDITTEXT        IDC_WORD_INPUT, 50, 8, 110, 14, ES_AUTOHSCROLL
  391. LTEXT           "Definition:", -1, 10, 30, 40, 8
  392. EDITTEXT        IDC_DEFINITION_INPUT, 50, 28, 200, 14, ES_AUTOHSCROLL
  393. PUSHBUTTON      "Add Word", IDC_ADD_WORD, 260, 8, 50, 14
  394. PUSHBUTTON      "Delete Word", IDC_DELETE_WORD, 260, 28, 50, 14
  395. PUSHBUTTON      "Edit Word", IDC_EDIT_WORD, 260, 48, 50, 14
  396. PUSHBUTTON      "View Definition", IDC_VIEW_DEFINITION, 200, 8, 50, 14
  397. PUSHBUTTON      "Clear", IDC_CLEAR_SEARCH, 170, 8, 20, 14
  398. LTEXT           "Search:", -1, 10, 50, 30, 8
  399. EDITTEXT        IDC_SEARCH_INPUT, 50, 48, 200, 14, ES_AUTOHSCROLL
  400. LISTBOX         IDC_LISTBOX, 10, 70, 300, 160, LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
  401. END
  402.  
  403. IDD_INPUT DIALOGEX 0, 0, 250, 120
  404. STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
  405. CAPTION "Input"
  406. FONT 8, "MS Shell Dlg", 400, 0, 0x1
  407. BEGIN
  408. LTEXT           "Input:", -1, 7, 14, 50, 8
  409. EDITTEXT        IDC_INPUT, 7, 30, 230, 20, ES_AUTOHSCROLL
  410. DEFPUSHBUTTON   "OK", IDOK, 70, 60, 50, 14
  411. PUSHBUTTON      "Cancel", IDCANCEL, 130, 60, 50, 14
  412. END
  413.  
  414. IDD_DEFINITION DIALOGEX 0, 0, 300, 200
  415. STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
  416. CAPTION "Definition"
  417. FONT 8, "MS Shell Dlg"
  418. BEGIN
  419. EDITTEXT        IDC_DEFINITION_EDIT, 7, 7, 286, 186, ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL
  420. END
  421.  
  422. resource2.h::
  423. #ifndef RESOURCE2_H
  424. #define RESOURCE2_H
  425.  
  426. #define IDD_MAINDIALOG                  101
  427. #define IDC_WORD_INPUT                  1001
  428. #define IDC_DEFINITION_INPUT            1002
  429. #define IDC_ADD_WORD                    1003
  430. #define IDC_DELETE_WORD                 1004
  431. #define IDC_SEARCH_INPUT                1005
  432. #define IDC_LISTBOX                     1006
  433. #define IDC_INPUT                       1007  // Add this line if you're using IDC_INPUT
  434. #define IDC_EDIT_WORD                   1008
  435. #define IDC_VIEW_DEFINITION             1009
  436. #define IDD_INPUT                       1010
  437. #define IDD_DEFINITION                  1011
  438. #define IDC_DEFINITION_EDIT             1012
  439. #define IDC_CLEAR_SEARCH                1013
  440.  
  441. #endif // RESOURCE2_H
  442.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement