Brandon Woodmansee : riched20: Implement EM_AUTOURLDETECT & EM_GETAUTOURLDETECT.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Mar 2 05:17:34 CST 2006


Module: wine
Branch: refs/heads/master
Commit: dee813b5ff599e3325ef8d9eb774a554d7e08ae2
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=dee813b5ff599e3325ef8d9eb774a554d7e08ae2

Author: Brandon Woodmansee <wood at socal.rr.com>
Date:   Wed Mar  1 10:49:42 2006 +0000

riched20: Implement EM_AUTOURLDETECT & EM_GETAUTOURLDETECT.

---

 dlls/riched20/editor.c       |  115 ++++++++++++++++++++++++++++++++++++++++--
 dlls/riched20/editor.h       |    2 -
 dlls/riched20/editstr.h      |    1 
 dlls/riched20/tests/editor.c |   75 +++++++++++++++++++++++++++
 4 files changed, 186 insertions(+), 7 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index feb99c3..a07f086 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -24,7 +24,7 @@
   API implementation status:
   
   Messages (ANSI versions not done yet)
-  - EM_AUTOURLDETECT 2.0
+  + EM_AUTOURLDETECT 2.0
   + EM_CANPASTE
   + EM_CANREDO 2.0
   + EM_CANUNDO
@@ -40,7 +40,7 @@
   - EM_FINDWORDBREAK
   - EM_FMTLINES
   - EM_FORMATRANGE
-  - EM_GETAUTOURLDETECT 2.0
+  + EM_GETAUTOURLDETECT 2.0
   - EM_GETBIDIOPTIONS 3.0
   - EM_GETCHARFORMAT (partly done)
   - EM_GETEDITSTYLE
@@ -1290,13 +1290,11 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
   
   switch(msg) {
   
-  UNSUPPORTED_MSG(EM_AUTOURLDETECT)
   UNSUPPORTED_MSG(EM_DISPLAYBAND)
   UNSUPPORTED_MSG(EM_EXLIMITTEXT)
   UNSUPPORTED_MSG(EM_FINDWORDBREAK)
   UNSUPPORTED_MSG(EM_FMTLINES)
   UNSUPPORTED_MSG(EM_FORMATRANGE)
-  UNSUPPORTED_MSG(EM_GETAUTOURLDETECT)
   UNSUPPORTED_MSG(EM_GETBIDIOPTIONS)
   UNSUPPORTED_MSG(EM_GETEDITSTYLE)
   UNSUPPORTED_MSG(EM_GETIMECOMPMODE)
@@ -1447,6 +1445,19 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
     ME_SendSelChange(editor);
     return 0;
   }
+  case EM_AUTOURLDETECT:
+  {
+    if (wParam==1 || wParam ==0) 
+    {
+        editor->AutoURLDetect_bEnable = (BOOL)wParam;
+        return 0;
+    }
+    return E_INVALIDARG;
+  }
+  case EM_GETAUTOURLDETECT:
+  {
+	return editor->AutoURLDetect_bEnable;
+  }
   case EM_EXSETSEL:
   {
     CHARRANGE *pRange = (CHARRANGE *)lParam;
@@ -2089,7 +2100,9 @@ LRESULT WINAPI RichEditANSIWndProc(HWND 
   case WM_CHAR: 
   {
     WCHAR wstr = LOWORD(wParam);
-
+    if (editor->AutoURLDetect_bEnable)
+      ME_AutoURLDetect(editor, wstr);
+        
     switch (wstr)
     {
     case 3: /* Ctrl-C */
@@ -2513,3 +2526,95 @@ LRESULT WINAPI REExtendedRegisterClass(v
 
   return result;
 }
+
+int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar) 
+{
+  struct prefix_s {
+    char *text;
+    int length;
+  } prefixes[12] = {
+    {"http:", 5},
+    {"file:", 6},
+    {"mailto:", 8},
+    {"ftp:", 5},
+    {"https:", 7},
+    {"gopher:", 8},
+    {"nntp:", 6},
+    {"prospero:", 10},
+    {"telnet:", 8},
+    {"news:", 6},
+    {"wais:", 6},
+    {"www.", 5}
+  };
+  CHARRANGE ins_pt;
+  int curf_ef, link_ef, def_ef;
+  int cur_prefx, prefx_cnt;
+  int sel_min, sel_max;
+  int car_pos = 0;
+  int text_pos=-1;
+  int URLmin, URLmax;
+  CHARRANGE url;
+  FINDTEXTA ft;
+  CHARFORMAT2W cur_format;
+  CHARFORMAT2W default_format;
+  CHARFORMAT2W link;
+  RichEditANSIWndProc(editor->hWnd, EM_EXGETSEL, (WPARAM) 0, (LPARAM) &ins_pt);
+  sel_min = ins_pt.cpMin;
+  sel_max = ins_pt.cpMax;
+  if (sel_min==sel_max) 
+    car_pos = sel_min;
+  if (sel_min!=sel_max)
+    car_pos = ME_GetTextLength(editor)+1;   
+  cur_format.cbSize = sizeof(cur_format);
+  default_format.cbSize = sizeof(default_format);
+  RichEditANSIWndProc(editor->hWnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cur_format);
+  RichEditANSIWndProc(editor->hWnd, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM) &default_format);
+  link.cbSize = sizeof(link);
+  link.dwMask = CFM_LINK | CFM_COLOR | CFM_UNDERLINE;
+  link.dwEffects = CFE_LINK | CFE_UNDERLINE;
+  link.crTextColor = RGB(0,0,255);
+  curf_ef = cur_format.dwEffects & link.dwEffects;
+  def_ef = default_format.dwEffects & link.dwEffects;
+  link_ef = link.dwEffects & link.dwEffects;
+  if (curf_ef == link_ef) 
+  {
+    if( curChar == '\n' || curChar=='\r' || curChar==' ') 
+    {
+      ME_SetSelection(editor, car_pos, car_pos);
+      RichEditANSIWndProc(editor->hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &default_format);
+      text_pos=-1;
+      return 0;
+    }
+  }
+  if (curf_ef == def_ef)
+  {
+    cur_prefx = 0;
+    prefx_cnt = (sizeof(prefixes)/sizeof(struct prefix_s))-1;
+    while (cur_prefx<=prefx_cnt) 
+    {
+      if (text_pos == -1) 
+      {
+        ft.lpstrText = prefixes[cur_prefx].text;
+        URLmin=max(0,(car_pos-prefixes[cur_prefx].length));
+        URLmax=max(0, car_pos);
+        if ((car_pos == 0) && (ME_GetTextLength(editor) != 0))
+        {
+        URLmax = ME_GetTextLength(editor)+1;
+        }
+        ft.chrg.cpMin = URLmin;
+        ft.chrg.cpMax = URLmax;
+        text_pos=RichEditANSIWndProc(editor->hWnd, EM_FINDTEXT, FR_DOWN, (LPARAM)&ft);   
+        cur_prefx++;
+      }
+      if (text_pos != -1) 
+      {
+        url.cpMin=text_pos;
+        url.cpMax=car_pos-1;
+        ME_SetCharFormat(editor, text_pos, (URLmax-text_pos), &link);
+        ME_Repaint(editor);
+        break;
+      }
+    }
+  }
+  return 0;
+}
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 7376e28..5cafda1 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -250,7 +250,7 @@ void ME_EmptyUndoStack(ME_TextEditor *ed
 int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF);
 ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset);
 void ME_StreamInFill(ME_InStream *stream);
-
+int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar);
 extern int me_debug;
 extern HANDLE me_heap;
 extern void DoWrap(ME_TextEditor *editor);
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 17cf2d8..0911e90 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -317,6 +317,7 @@ typedef struct tagME_TextEditor
    *TM_SINGLECODEPAGE or TM_MULTICODEPAGE*/
   int mode;
   BOOL bHideSelection;
+  BOOL AutoURLDetect_bEnable;
 } ME_TextEditor;
 
 typedef struct tagME_Context
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index 4f34a66..8835f08 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -536,6 +536,79 @@ static void test_EM_SETOPTIONS()
     DestroyWindow(hwndRichEdit);
 }
 
+static void check_CFE_LINK_rcvd(HWND hwnd, int is_url)
+{
+  CHARFORMAT2W text_format;
+  int link_present = 0;
+  text_format.cbSize = sizeof(text_format);
+  SendMessage(hwnd, EM_SETSEL, 0, 0);
+  SendMessage(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &text_format);
+  link_present = text_format.dwEffects & CFE_LINK;
+  if (is_url) 
+  { /* control text is url; should get CFE_LINK */
+	ok(0 != link_present, "URL Case: CFE_LINK not set.\n");
+  }
+  else 
+  {
+    ok(0 == link_present, "Non-URL Case: CFE_LINK set.\n");
+  }
+}
+
+static HWND new_static_wnd(HWND parent) {
+  return new_window("Static", 0, parent);
+}
+
+static void test_EM_AUTOURLDETECT(void)
+{
+  struct urls_s {
+    char *text;
+    int is_url;
+  } urls[12] = {
+    {"winehq.org", 0},
+    {"http://www.winehq.org", 1},
+    {"http//winehq.org", 0},
+    {"ww.winehq.org", 0},
+    {"www.winehq.org", 1},
+    {"ftp://192.168.1.1", 1},
+    {"ftp//192.168.1.1", 0},
+    {"mailto:your at email.com", 1},    
+    {"prospero:prosperoserver", 1},
+    {"telnet:test", 1},
+    {"news:newserver", 1},
+    {"wais:waisserver", 1}  
+  };
+
+  int i;
+  int urlRet=-1;
+  HWND hwndRichEdit, parent;
+
+  parent = new_static_wnd(NULL);
+  hwndRichEdit = new_richedit(parent);
+  /* Try and pass EM_AUTOURLDETECT some test wParam values */
+  urlRet=SendMessage(hwndRichEdit, EM_AUTOURLDETECT, FALSE, 0);
+  ok(urlRet==0, "Good wParam: urlRet is: %d\n", urlRet);
+  urlRet=SendMessage(hwndRichEdit, EM_AUTOURLDETECT, 1, 0);
+  ok(urlRet==0, "Good wParam2: urlRet is: %d\n", urlRet);
+  /* Windows returns -2147024809 (0x80070057) on bad wParam values */
+  urlRet=SendMessage(hwndRichEdit, EM_AUTOURLDETECT, 8, 0);
+  ok(urlRet==E_INVALIDARG, "Bad wParam: urlRet is: %d\n", urlRet);
+  urlRet=SendMessage(hwndRichEdit, EM_AUTOURLDETECT, (WPARAM)"h", (LPARAM)"h");
+  ok(urlRet==E_INVALIDARG, "Bad wParam2: urlRet is: %d\n", urlRet);
+  /* for each url, check the text to see if CFE_LINK effect is present */
+  for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
+    SendMessage(hwndRichEdit, EM_AUTOURLDETECT, FALSE, 0);
+    SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) urls[i].text);
+    SendMessage(hwndRichEdit, WM_CHAR, 0, 0);
+    check_CFE_LINK_rcvd(hwndRichEdit, 0);
+    SendMessage(hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0);
+    SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) urls[i].text);
+    SendMessage(hwndRichEdit, WM_CHAR, 0, 0);
+    check_CFE_LINK_rcvd(hwndRichEdit, urls[i].is_url);
+  }
+  DestroyWindow(hwndRichEdit);
+  DestroyWindow(parent);
+}
+
 static void test_EM_SCROLL()
 {
   int i, j;
@@ -686,7 +759,6 @@ START_TEST( editor )
    * RICHED20.DLL, so the linker doesn't actually link to it. */
   hmoduleRichEdit = LoadLibrary("RICHED20.DLL");
   ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
-
   test_EM_FINDTEXT();
   test_EM_SCROLLCARET();
   test_EM_SCROLL();
@@ -694,6 +766,7 @@ START_TEST( editor )
   test_TM_PLAINTEXT();
   test_EM_SETOPTIONS();
   test_WM_GETTEXT();
+  test_EM_AUTOURLDETECT();
 
   /* Set the environment variable WINETEST_RICHED20 to keep windows
    * responsive and open for 30 seconds. This is useful for debugging.




More information about the wine-cvs mailing list